code-battles 1.7.0 → 1.7.2

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.
Files changed (52) hide show
  1. package/dist/cjs/index.js +2153 -1954
  2. package/dist/cjs/styles.css +2 -1
  3. package/dist/cjs/types/components/DataTable.d.ts +21 -0
  4. package/dist/cjs/types/components/ResultStaticsTable.d.ts +3 -0
  5. package/dist/cjs/types/configuration.d.ts +0 -1
  6. package/dist/code_battles/battles.py +22 -9
  7. package/dist/code_battles/utilities.py +5 -1
  8. package/dist/esm/index.js +2154 -1955
  9. package/dist/esm/styles.css +2 -1
  10. package/dist/esm/types/components/DataTable.d.ts +21 -0
  11. package/dist/esm/types/components/ResultStaticsTable.d.ts +3 -0
  12. package/dist/esm/types/configuration.d.ts +0 -1
  13. package/dist/index.d.ts +0 -1
  14. package/dist/pyscript/codemirror-eKulCBrd.js +2 -0
  15. package/dist/pyscript/codemirror-eKulCBrd.js.map +1 -0
  16. package/dist/pyscript/codemirror_commands-BVu_0Pnj.js +2 -0
  17. package/dist/pyscript/codemirror_commands-BVu_0Pnj.js.map +1 -0
  18. package/dist/pyscript/codemirror_lang-python-a2LxSo5G.js +2 -0
  19. package/dist/pyscript/codemirror_lang-python-a2LxSo5G.js.map +1 -0
  20. package/dist/pyscript/codemirror_language-_2pXlKJ9.js +2 -0
  21. package/dist/pyscript/codemirror_language-_2pXlKJ9.js.map +1 -0
  22. package/dist/pyscript/codemirror_view-DMW9kQlJ.js +2 -0
  23. package/dist/pyscript/codemirror_view-DMW9kQlJ.js.map +1 -0
  24. package/dist/pyscript/core-DezwbZpG.js +4 -0
  25. package/dist/pyscript/core-DezwbZpG.js.map +1 -0
  26. package/dist/pyscript/core.js +1 -1
  27. package/dist/pyscript/deprecations-manager-B1bDno27.js +2 -0
  28. package/dist/pyscript/deprecations-manager-B1bDno27.js.map +1 -0
  29. package/dist/pyscript/donkey-DNl0ASkM.js +2 -0
  30. package/dist/pyscript/donkey-DNl0ASkM.js.map +1 -0
  31. package/dist/pyscript/error-DmRE4Y-7.js +2 -0
  32. package/dist/pyscript/error-DmRE4Y-7.js.map +1 -0
  33. package/dist/pyscript/index-DkgvWIf-.js +2 -0
  34. package/dist/pyscript/index-DkgvWIf-.js.map +1 -0
  35. package/dist/pyscript/mpy-BoY0tVRD.js +2 -0
  36. package/dist/pyscript/mpy-BoY0tVRD.js.map +1 -0
  37. package/dist/pyscript/py-DsQqgZuM.js +2 -0
  38. package/dist/pyscript/py-DsQqgZuM.js.map +1 -0
  39. package/dist/pyscript/py-editor-DZkG_or6.js +2 -0
  40. package/dist/pyscript/py-editor-DZkG_or6.js.map +1 -0
  41. package/dist/pyscript/py-game-D0Z4YnzZ.js +2 -0
  42. package/dist/pyscript/py-game-D0Z4YnzZ.js.map +1 -0
  43. package/dist/pyscript/py-terminal-DYHK7LJ0.js +2 -0
  44. package/dist/pyscript/py-terminal-DYHK7LJ0.js.map +1 -0
  45. package/dist/pyscript/service-worker.js +1 -0
  46. package/dist/pyscript/storage.js +1 -1
  47. package/dist/pyscript/storage.js.map +1 -1
  48. package/dist/pyscript/xterm-CVv2fC4I.js +2 -0
  49. package/dist/pyscript/xterm-CVv2fC4I.js.map +1 -0
  50. package/dist/pyscript/zip-D13-hp9W.js +2 -0
  51. package/dist/pyscript/zip-D13-hp9W.js.map +1 -0
  52. package/package.json +14 -14
package/dist/esm/index.js CHANGED
@@ -2,7 +2,7 @@ import '@mantine/core/styles.css';
2
2
  import '@mantine/dates/styles.css';
3
3
  import '@mantine/notifications/styles.css';
4
4
  import '@mantine/dropzone/styles.css';
5
- import { TextInput, Button, Alert, Slider, Box, Select, NumberInput, Table, Badge, Autocomplete, Loader, MantineProvider } from '@mantine/core';
5
+ import { TextInput, Button, Alert, Slider, Box, Select, NumberInput, Table, Badge, Autocomplete, useMantineTheme, ActionIcon, UnstyledButton, Checkbox, Loader, MantineProvider } from '@mantine/core';
6
6
  import { TimeInput, DatesProvider } from '@mantine/dates';
7
7
  import { useColorScheme, useViewportSize } from '@mantine/hooks';
8
8
  import { notifications, Notifications } from '@mantine/notifications';
@@ -374,8 +374,8 @@ const updatePointModifier = () => {
374
374
  if (results[round.players.join(", ")] &&
375
375
  results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
376
376
  for (const result of results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
377
- const first = round.players[result[0]];
378
- const second = round.players[result[1]];
377
+ const first = round.players[result.places[0]];
378
+ const second = round.players[result.places[1]];
379
379
  if (!pointModifier[first]) {
380
380
  pointModifier[first] = 0;
381
381
  }
@@ -884,9 +884,9 @@ function requireCheckPropTypes () {
884
884
  var printWarning = function() {};
885
885
 
886
886
  if (process.env.NODE_ENV !== 'production') {
887
- var ReactPropTypesSecret = requireReactPropTypesSecret();
887
+ var ReactPropTypesSecret = /*@__PURE__*/ requireReactPropTypesSecret();
888
888
  var loggedTypeFailures = {};
889
- var has = requireHas();
889
+ var has = /*@__PURE__*/ requireHas();
890
890
 
891
891
  printWarning = function(text) {
892
892
  var message = 'Warning: ' + text;
@@ -995,9 +995,9 @@ function requireFactoryWithTypeCheckers () {
995
995
  var ReactIs = requireReactIs();
996
996
  var assign = requireObjectAssign();
997
997
 
998
- var ReactPropTypesSecret = requireReactPropTypesSecret();
999
- var has = requireHas();
1000
- var checkPropTypes = requireCheckPropTypes();
998
+ var ReactPropTypesSecret = /*@__PURE__*/ requireReactPropTypesSecret();
999
+ var has = /*@__PURE__*/ requireHas();
1000
+ var checkPropTypes = /*@__PURE__*/ requireCheckPropTypes();
1001
1001
 
1002
1002
  var printWarning = function() {};
1003
1003
 
@@ -1610,7 +1610,7 @@ function requireFactoryWithThrowingShims () {
1610
1610
  if (hasRequiredFactoryWithThrowingShims) return factoryWithThrowingShims;
1611
1611
  hasRequiredFactoryWithThrowingShims = 1;
1612
1612
 
1613
- var ReactPropTypesSecret = requireReactPropTypesSecret();
1613
+ var ReactPropTypesSecret = /*@__PURE__*/ requireReactPropTypesSecret();
1614
1614
 
1615
1615
  function emptyFunction() {}
1616
1616
  function emptyFunctionWithReset() {}
@@ -1674,20 +1674,27 @@ function requireFactoryWithThrowingShims () {
1674
1674
  * LICENSE file in the root directory of this source tree.
1675
1675
  */
1676
1676
 
1677
- if (process.env.NODE_ENV !== 'production') {
1678
- var ReactIs = requireReactIs();
1679
-
1680
- // By explicitly using `prop-types` you are opting into new development behavior.
1681
- // http://fb.me/prop-types-in-prod
1682
- var throwOnDirectAccess = true;
1683
- propTypes.exports = requireFactoryWithTypeCheckers()(ReactIs.isElement, throwOnDirectAccess);
1684
- } else {
1685
- // By explicitly using `prop-types` you are opting into new production behavior.
1686
- // http://fb.me/prop-types-in-prod
1687
- propTypes.exports = requireFactoryWithThrowingShims()();
1677
+ var hasRequiredPropTypes;
1678
+
1679
+ function requirePropTypes () {
1680
+ if (hasRequiredPropTypes) return propTypes.exports;
1681
+ hasRequiredPropTypes = 1;
1682
+ if (process.env.NODE_ENV !== 'production') {
1683
+ var ReactIs = requireReactIs();
1684
+
1685
+ // By explicitly using `prop-types` you are opting into new development behavior.
1686
+ // http://fb.me/prop-types-in-prod
1687
+ var throwOnDirectAccess = true;
1688
+ propTypes.exports = /*@__PURE__*/ requireFactoryWithTypeCheckers()(ReactIs.isElement, throwOnDirectAccess);
1689
+ } else {
1690
+ // By explicitly using `prop-types` you are opting into new production behavior.
1691
+ // http://fb.me/prop-types-in-prod
1692
+ propTypes.exports = /*@__PURE__*/ requireFactoryWithThrowingShims()();
1693
+ }
1694
+ return propTypes.exports;
1688
1695
  }
1689
1696
 
1690
- var propTypesExports = propTypes.exports;
1697
+ var propTypesExports = /*@__PURE__*/ requirePropTypes();
1691
1698
 
1692
1699
  function _classCallCheck(instance, Constructor) {
1693
1700
  if (!(instance instanceof Constructor)) {
@@ -2528,7 +2535,7 @@ const RunSimulationBlock = () => {
2528
2535
  };
2529
2536
  const startRunNoUI = () => {
2530
2537
  setRunningNoUI(true);
2531
- runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
2538
+ runNoUI(getFullParameters(), apis, playerBots, seed.toString(), true);
2532
2539
  };
2533
2540
  const startRunNoUIN = (n) => {
2534
2541
  setLocalStorage("Results", {});
@@ -2565,7 +2572,7 @@ const RunSimulationBlock = () => {
2565
2572
  const currentResults = results[playerBots.join(", ")][JSON.stringify(getFullParameters())];
2566
2573
  const winCounts = {};
2567
2574
  for (const result of currentResults) {
2568
- const winner = playerBots[result[0]];
2575
+ const winner = playerBots[result.places[0]];
2569
2576
  if (!winCounts[winner]) {
2570
2577
  winCounts[winner] = 1;
2571
2578
  }
@@ -2786,6 +2793,155 @@ const NotFoundPage = () => {
2786
2793
  React.createElement("p", null, "Make sure the URL is correct.")));
2787
2794
  };
2788
2795
 
2796
+ const DataTable = ({ tableName, data, renderValue, renderHead, disableSort, hideIfEmpty, selectable, selectedRows, setSelectedRows, defaultSort, defaultReversed, stickyFirstColumn, }) => {
2797
+ var _a, _b;
2798
+ const [sortByColumn, setSortByColumn] = useState(defaultSort !== null && defaultSort !== void 0 ? defaultSort : 0);
2799
+ const [reversed, setReversed] = useState(defaultReversed !== null && defaultReversed !== void 0 ? defaultReversed : false);
2800
+ const [search, setSearch] = useState("");
2801
+ const theme = useMantineTheme();
2802
+ const colorScheme = useColorScheme();
2803
+ if (hideIfEmpty && data.body.length === 0) {
2804
+ return React.createElement(React.Fragment, null);
2805
+ }
2806
+ const reverseValue = reversed ? -1 : 1;
2807
+ const id = (_, __, value) => value;
2808
+ renderValue = renderValue !== null && renderValue !== void 0 ? renderValue : id;
2809
+ const headId = (value) => value;
2810
+ renderHead = renderHead !== null && renderHead !== void 0 ? renderHead : headId;
2811
+ const bodyIndices = [];
2812
+ for (let i = 0; i < data.body.length; i++) {
2813
+ bodyIndices.push(i);
2814
+ }
2815
+ const sortedIndices = bodyIndices
2816
+ .filter((i) => data.body[i].some((x, j) => {
2817
+ var _a;
2818
+ return (x === null || x === void 0 ? void 0 : x.includes(search)) ||
2819
+ ((_a = renderValue(i, data.head[j], x)) === null || _a === void 0 ? void 0 : _a.toString().includes(search));
2820
+ }))
2821
+ .sort((a, b) => {
2822
+ var _a, _b;
2823
+ if (disableSort) {
2824
+ return 1;
2825
+ }
2826
+ const aValue = (_a = data.body[a][sortByColumn]) !== null && _a !== void 0 ? _a : "";
2827
+ const bValue = (_b = data.body[b][sortByColumn]) !== null && _b !== void 0 ? _b : "";
2828
+ let difference = parseInt(bValue) - parseInt(aValue);
2829
+ if (isNaN(difference)) {
2830
+ return reverseValue * (aValue === null || aValue === void 0 ? void 0 : aValue.localeCompare(bValue));
2831
+ }
2832
+ return reverseValue * difference;
2833
+ });
2834
+ const displayData = {
2835
+ head: data.head.map(renderHead),
2836
+ body: sortedIndices.map((rowIndex) => data.body[rowIndex].map((value, columnIndex) => renderValue(rowIndex, data.head[columnIndex], value))),
2837
+ };
2838
+ return (React.createElement(React.Fragment, null,
2839
+ React.createElement(TextInput, { mb: "xs", w: 400, maw: "100%", placeholder: "Search", leftSection: React.createElement("i", { className: "fa-solid fa-magnifying-glass" }), rightSection: search !== "" ? (React.createElement(ActionIcon, { onClick: () => setSearch(""), variant: "transparent", color: "default", size: 15 },
2840
+ React.createElement("i", { className: "fa-solid fa-xmark" }))) : undefined, value: search, onChange: (e) => setSearch(e.currentTarget.value) }),
2841
+ React.createElement("div", { style: { maxWidth: "100%", overflow: "auto", maxHeight: 500 } },
2842
+ React.createElement(Table, { horizontalSpacing: 7.5, verticalSpacing: 7.5 },
2843
+ React.createElement(Table.Thead, { style: {
2844
+ position: "sticky",
2845
+ top: 0,
2846
+ backgroundColor: colorScheme === "dark" ? theme.colors.dark[7] : "white",
2847
+ zIndex: 101,
2848
+ } },
2849
+ React.createElement(Table.Tr, { h: 1 },
2850
+ selectable && React.createElement(Table.Th, null), (_a = displayData.head) === null || _a === void 0 ? void 0 :
2851
+ _a.map((element, columnIndex) => (React.createElement(Table.Th, { key: columnIndex, style: {
2852
+ padding: 0,
2853
+ verticalAlign: "top",
2854
+ height: "inherit",
2855
+ } }, element !== "" && (React.createElement(UnstyledButton, { h: "100%", className: "control", style: {
2856
+ display: "flex",
2857
+ flexDirection: "column",
2858
+ minWidth: 100,
2859
+ }, onClick: disableSort
2860
+ ? undefined
2861
+ : () => {
2862
+ if (sortByColumn === columnIndex) {
2863
+ setReversed((r) => !r);
2864
+ }
2865
+ else {
2866
+ setSortByColumn(columnIndex);
2867
+ }
2868
+ } },
2869
+ disableSort || (React.createElement("i", { style: { fontSize: 14, marginBottom: 5 }, className: sortByColumn === columnIndex
2870
+ ? reversed
2871
+ ? "fa-solid fa-sort-up"
2872
+ : "fa-solid fa-sort-down"
2873
+ : "fa-solid fa-sort" })),
2874
+ element))))))),
2875
+ React.createElement(Table.Tbody, null, (_b = displayData.body) === null || _b === void 0 ? void 0 : _b.map((row, rowIndex) => {
2876
+ const realIndex = sortedIndices[rowIndex];
2877
+ return (React.createElement(Table.Tr, { key: rowIndex },
2878
+ selectable && (React.createElement(Table.Td, null,
2879
+ React.createElement(Checkbox, { checked: selectedRows === null || selectedRows === void 0 ? void 0 : selectedRows.includes(realIndex), onChange: (e) => {
2880
+ if (setSelectedRows) {
2881
+ if (e.currentTarget.checked) {
2882
+ setSelectedRows((s) => [...s, realIndex]);
2883
+ }
2884
+ else {
2885
+ setSelectedRows((s) => s.filter((x) => x !== realIndex));
2886
+ }
2887
+ }
2888
+ } }))),
2889
+ row.map((value, valueIndex) => (React.createElement(Table.Td, { key: valueIndex, style: Object.assign({ whiteSpace: "nowrap" }, (stickyFirstColumn && valueIndex === 0
2890
+ ? {
2891
+ position: "sticky",
2892
+ right: 0,
2893
+ backgroundColor: colorScheme === "dark"
2894
+ ? theme.colors.dark[7]
2895
+ : "white",
2896
+ zIndex: 100,
2897
+ }
2898
+ : {})) }, value)))));
2899
+ }))))));
2900
+ };
2901
+
2902
+ const ResultStatisticsTable = () => {
2903
+ var _a, _b, _c, _d, _e;
2904
+ const [results] = useLocalStorage({
2905
+ key: "Results",
2906
+ defaultValue: {},
2907
+ });
2908
+ const [rounds] = useLocalStorage({
2909
+ key: "Rounds",
2910
+ defaultValue: [],
2911
+ });
2912
+ const [currentRound] = useLocalStorage({
2913
+ key: "Current Round",
2914
+ defaultValue: 0,
2915
+ });
2916
+ const navigate = useNavigate();
2917
+ const round = rounds[currentRound];
2918
+ if (!round) {
2919
+ return React.createElement(React.Fragment, null);
2920
+ }
2921
+ const statistics = Object.keys((_d = (_c = ((_b = Object.values((_a = Object.values(results !== null && results !== void 0 ? results : {})[0]) !== null && _a !== void 0 ? _a : {})[0]) !== null && _b !== void 0 ? _b : [])[0]) === null || _c === void 0 ? void 0 : _c.statistics) !== null && _d !== void 0 ? _d : {});
2922
+ const roundResults = ((_e = (results !== null && results !== void 0 ? results : {})[round.players.join(", ")]) !== null && _e !== void 0 ? _e : {})[JSON.stringify(round.parameters)];
2923
+ if (!roundResults) {
2924
+ return React.createElement(React.Fragment, null);
2925
+ }
2926
+ return (React.createElement("div", { style: {
2927
+ display: "flex",
2928
+ flexDirection: "column",
2929
+ alignItems: "center",
2930
+ marginTop: 10,
2931
+ } },
2932
+ React.createElement(DataTable, { tableName: "Results", data: {
2933
+ head: ["Seed"].concat(statistics),
2934
+ body: roundResults.map((result) => [result.seed].concat(statistics.map((statistic) => { var _a; return ((_a = result === null || result === void 0 ? void 0 : result.statistics) !== null && _a !== void 0 ? _a : {})[statistic].toString(); }))),
2935
+ }, renderValue: (rowIndex, columnName, value) => {
2936
+ if (columnName === "Seed") {
2937
+ return (React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), onClick: () => navigate(`/simulation/${round.players.map(encodeURIComponent).join(",")}?seed=${value}&${Object.keys(round.parameters)
2938
+ .map((p) => `${p}=${encodeURIComponent(round.parameters[p])}`)
2939
+ .join("&")}`) }, "Play"));
2940
+ }
2941
+ return React.createElement(React.Fragment, { key: rowIndex }, value);
2942
+ } })));
2943
+ };
2944
+
2789
2945
  let currentParameters;
2790
2946
  let currentPlayers;
2791
2947
  const Round = () => {
@@ -2875,11 +3031,12 @@ const Round = () => {
2875
3031
  roundIterations !== 1 && (React.createElement("th", { style: { width: "35%" } }, "Results")),
2876
3032
  React.createElement("th", null))),
2877
3033
  React.createElement("tbody", null, rounds.map((round, index) => {
3034
+ var _a, _b;
2878
3035
  const winCounts = {};
2879
3036
  if (results[round.players.join(", ")] !== undefined) {
2880
3037
  const currentResults = results[round.players.join(", ")][JSON.stringify(round.parameters)];
2881
3038
  for (const result of currentResults) {
2882
- const winner = round.players[result[0]];
3039
+ const winner = round.players[result.places[0]];
2883
3040
  if (!winCounts[winner]) {
2884
3041
  winCounts[winner] = 1;
2885
3042
  }
@@ -2897,15 +3054,18 @@ const Round = () => {
2897
3054
  React.createElement("td", null, round.players.map((player, index) => (React.createElement("img", { key: index, src: `/images/teams/${player.toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } })))),
2898
3055
  roundIterations === 1 && (React.createElement(React.Fragment, null,
2899
3056
  React.createElement("td", null, results[round.players.join(", ")] !== undefined &&
2900
- results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][0]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))),
3057
+ results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${(_a = round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][0]]) === null || _a === void 0 ? void 0 : _a.toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))),
2901
3058
  React.createElement("td", null, results[round.players.join(", ")] !== undefined &&
2902
- results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][1]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))))),
3059
+ results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${(_b = round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][1]]) === null || _b === void 0 ? void 0 : _b.toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))))),
2903
3060
  roundIterations !== 1 && (React.createElement("td", null, winners.map((winner, index) => (React.createElement("p", { key: index },
2904
3061
  winner,
2905
3062
  ": ",
2906
3063
  winCounts[winner]))))),
2907
3064
  React.createElement("td", null,
2908
3065
  React.createElement(Button.Group, { orientation: "vertical" },
3066
+ React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-hand-pointer" }), size: "xs", onClick: () => {
3067
+ setLocalStorage("Current Round", index);
3068
+ } }, "Select"),
2909
3069
  React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.players.map(encodeURIComponent).join(",")}?showcase=true&${Object.keys(round.parameters)
2910
3070
  .map((p) => `${p}=${encodeURIComponent(round.parameters[p])}`)
2911
3071
  .join("&")}`) }, "Simulate"),
@@ -2979,7 +3139,8 @@ const Round = () => {
2979
3139
  flexDirection: clientWidth >= 700 ? "row" : "column",
2980
3140
  } },
2981
3141
  React.createElement(TournamentBlock, { title: "Before", inline: true }),
2982
- React.createElement(TournamentBlock, { title: "After", inline: true, pointModifier: pointModifier }))))));
3142
+ React.createElement(TournamentBlock, { title: "After", inline: true, pointModifier: pointModifier }))),
3143
+ React.createElement(ResultStatisticsTable, null))));
2983
3144
  };
2984
3145
 
2985
3146
  const SettingsPage = () => {
@@ -3415,7 +3576,7 @@ const TopPane = () => {
3415
3576
  };
3416
3577
 
3417
3578
  const CodeBattles = ({ configuration, routes, blocks }) => {
3418
- var _a, _b, _c, _d, _e, _f, _g, _h;
3579
+ var _a, _b, _c, _d, _e, _f;
3419
3580
  const colorScheme = useColorScheme();
3420
3581
  const firebase = initializeApp(configuration.firebase);
3421
3582
  const firestore = getFirestore(firebase);
@@ -3426,7 +3587,6 @@ const CodeBattles = ({ configuration, routes, blocks }) => {
3426
3587
  locale: (_b = (_a = configuration.dates) === null || _a === void 0 ? void 0 : _a.locale) !== null && _b !== void 0 ? _b : "en",
3427
3588
  firstDayOfWeek: (_d = (_c = configuration.dates) === null || _c === void 0 ? void 0 : _c.firstDayOfWeek) !== null && _d !== void 0 ? _d : 0,
3428
3589
  weekendDays: (_f = (_e = configuration.dates) === null || _e === void 0 ? void 0 : _e.weekendDays) !== null && _f !== void 0 ? _f : [],
3429
- timezone: (_h = (_g = configuration.dates) === null || _g === void 0 ? void 0 : _g.timezone) !== null && _h !== void 0 ? _h : "UTC",
3430
3590
  } },
3431
3591
  React.createElement(BrowserRouter, null,
3432
3592
  React.createElement(Notifications, null),
@@ -3463,2272 +3623,2303 @@ const CodeBattles = ({ configuration, routes, blocks }) => {
3463
3623
 
3464
3624
  var prism = {exports: {}};
3465
3625
 
3466
- (function (module) {
3467
- /* **********************************************
3468
- Begin prism-core.js
3469
- ********************************************** */
3470
-
3471
- /// <reference lib="WebWorker"/>
3626
+ var hasRequiredPrism;
3472
3627
 
3473
- var _self = (typeof window !== 'undefined')
3474
- ? window // if in browser
3475
- : (
3476
- (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
3477
- ? self // if in worker
3478
- : {} // if in node js
3479
- );
3628
+ function requirePrism () {
3629
+ if (hasRequiredPrism) return prism.exports;
3630
+ hasRequiredPrism = 1;
3631
+ (function (module) {
3632
+ /* **********************************************
3633
+ Begin prism-core.js
3634
+ ********************************************** */
3480
3635
 
3481
- /**
3482
- * Prism: Lightweight, robust, elegant syntax highlighting
3483
- *
3484
- * @license MIT <https://opensource.org/licenses/MIT>
3485
- * @author Lea Verou <https://lea.verou.me>
3486
- * @namespace
3487
- * @public
3488
- */
3489
- var Prism = (function (_self) {
3636
+ /// <reference lib="WebWorker"/>
3490
3637
 
3491
- // Private helper vars
3492
- var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
3493
- var uniqueId = 0;
3638
+ var _self = (typeof window !== 'undefined')
3639
+ ? window // if in browser
3640
+ : (
3641
+ (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
3642
+ ? self // if in worker
3643
+ : {} // if in node js
3644
+ );
3494
3645
 
3495
- // The grammar object for plaintext
3496
- var plainTextGrammar = {};
3646
+ /**
3647
+ * Prism: Lightweight, robust, elegant syntax highlighting
3648
+ *
3649
+ * @license MIT <https://opensource.org/licenses/MIT>
3650
+ * @author Lea Verou <https://lea.verou.me>
3651
+ * @namespace
3652
+ * @public
3653
+ */
3654
+ var Prism = (function (_self) {
3497
3655
 
3656
+ // Private helper vars
3657
+ var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
3658
+ var uniqueId = 0;
3498
3659
 
3499
- var _ = {
3500
- /**
3501
- * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
3502
- * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
3503
- * additional languages or plugins yourself.
3504
- *
3505
- * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
3506
- *
3507
- * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
3508
- * empty Prism object into the global scope before loading the Prism script like this:
3509
- *
3510
- * ```js
3511
- * window.Prism = window.Prism || {};
3512
- * Prism.manual = true;
3513
- * // add a new <script> to load Prism's script
3514
- * ```
3515
- *
3516
- * @default false
3517
- * @type {boolean}
3518
- * @memberof Prism
3519
- * @public
3520
- */
3521
- manual: _self.Prism && _self.Prism.manual,
3522
- /**
3523
- * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
3524
- * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
3525
- * own worker, you don't want it to do this.
3526
- *
3527
- * By setting this value to `true`, Prism will not add its own listeners to the worker.
3528
- *
3529
- * You obviously have to change this value before Prism executes. To do this, you can add an
3530
- * empty Prism object into the global scope before loading the Prism script like this:
3531
- *
3532
- * ```js
3533
- * window.Prism = window.Prism || {};
3534
- * Prism.disableWorkerMessageHandler = true;
3535
- * // Load Prism's script
3536
- * ```
3537
- *
3538
- * @default false
3539
- * @type {boolean}
3540
- * @memberof Prism
3541
- * @public
3542
- */
3543
- disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
3660
+ // The grammar object for plaintext
3661
+ var plainTextGrammar = {};
3544
3662
 
3545
- /**
3546
- * A namespace for utility methods.
3547
- *
3548
- * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
3549
- * change or disappear at any time.
3550
- *
3551
- * @namespace
3552
- * @memberof Prism
3553
- */
3554
- util: {
3555
- encode: function encode(tokens) {
3556
- if (tokens instanceof Token) {
3557
- return new Token(tokens.type, encode(tokens.content), tokens.alias);
3558
- } else if (Array.isArray(tokens)) {
3559
- return tokens.map(encode);
3560
- } else {
3561
- return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
3562
- }
3563
- },
3564
3663
 
3664
+ var _ = {
3565
3665
  /**
3566
- * Returns the name of the type of the given value.
3666
+ * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
3667
+ * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
3668
+ * additional languages or plugins yourself.
3567
3669
  *
3568
- * @param {any} o
3569
- * @returns {string}
3570
- * @example
3571
- * type(null) === 'Null'
3572
- * type(undefined) === 'Undefined'
3573
- * type(123) === 'Number'
3574
- * type('foo') === 'String'
3575
- * type(true) === 'Boolean'
3576
- * type([1, 2]) === 'Array'
3577
- * type({}) === 'Object'
3578
- * type(String) === 'Function'
3579
- * type(/abc+/) === 'RegExp'
3670
+ * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
3671
+ *
3672
+ * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
3673
+ * empty Prism object into the global scope before loading the Prism script like this:
3674
+ *
3675
+ * ```js
3676
+ * window.Prism = window.Prism || {};
3677
+ * Prism.manual = true;
3678
+ * // add a new <script> to load Prism's script
3679
+ * ```
3680
+ *
3681
+ * @default false
3682
+ * @type {boolean}
3683
+ * @memberof Prism
3684
+ * @public
3580
3685
  */
3581
- type: function (o) {
3582
- return Object.prototype.toString.call(o).slice(8, -1);
3583
- },
3584
-
3686
+ manual: _self.Prism && _self.Prism.manual,
3585
3687
  /**
3586
- * Returns a unique number for the given object. Later calls will still return the same number.
3688
+ * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
3689
+ * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
3690
+ * own worker, you don't want it to do this.
3691
+ *
3692
+ * By setting this value to `true`, Prism will not add its own listeners to the worker.
3693
+ *
3694
+ * You obviously have to change this value before Prism executes. To do this, you can add an
3695
+ * empty Prism object into the global scope before loading the Prism script like this:
3696
+ *
3697
+ * ```js
3698
+ * window.Prism = window.Prism || {};
3699
+ * Prism.disableWorkerMessageHandler = true;
3700
+ * // Load Prism's script
3701
+ * ```
3587
3702
  *
3588
- * @param {Object} obj
3589
- * @returns {number}
3703
+ * @default false
3704
+ * @type {boolean}
3705
+ * @memberof Prism
3706
+ * @public
3590
3707
  */
3591
- objId: function (obj) {
3592
- if (!obj['__id']) {
3593
- Object.defineProperty(obj, '__id', { value: ++uniqueId });
3594
- }
3595
- return obj['__id'];
3596
- },
3708
+ disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
3597
3709
 
3598
3710
  /**
3599
- * Creates a deep clone of the given object.
3711
+ * A namespace for utility methods.
3600
3712
  *
3601
- * The main intended use of this function is to clone language definitions.
3713
+ * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
3714
+ * change or disappear at any time.
3602
3715
  *
3603
- * @param {T} o
3604
- * @param {Record<number, any>} [visited]
3605
- * @returns {T}
3606
- * @template T
3716
+ * @namespace
3717
+ * @memberof Prism
3607
3718
  */
3608
- clone: function deepClone(o, visited) {
3609
- visited = visited || {};
3610
-
3611
- var clone; var id;
3612
- switch (_.util.type(o)) {
3613
- case 'Object':
3614
- id = _.util.objId(o);
3615
- if (visited[id]) {
3616
- return visited[id];
3617
- }
3618
- clone = /** @type {Record<string, any>} */ ({});
3619
- visited[id] = clone;
3719
+ util: {
3720
+ encode: function encode(tokens) {
3721
+ if (tokens instanceof Token) {
3722
+ return new Token(tokens.type, encode(tokens.content), tokens.alias);
3723
+ } else if (Array.isArray(tokens)) {
3724
+ return tokens.map(encode);
3725
+ } else {
3726
+ return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
3727
+ }
3728
+ },
3729
+
3730
+ /**
3731
+ * Returns the name of the type of the given value.
3732
+ *
3733
+ * @param {any} o
3734
+ * @returns {string}
3735
+ * @example
3736
+ * type(null) === 'Null'
3737
+ * type(undefined) === 'Undefined'
3738
+ * type(123) === 'Number'
3739
+ * type('foo') === 'String'
3740
+ * type(true) === 'Boolean'
3741
+ * type([1, 2]) === 'Array'
3742
+ * type({}) === 'Object'
3743
+ * type(String) === 'Function'
3744
+ * type(/abc+/) === 'RegExp'
3745
+ */
3746
+ type: function (o) {
3747
+ return Object.prototype.toString.call(o).slice(8, -1);
3748
+ },
3749
+
3750
+ /**
3751
+ * Returns a unique number for the given object. Later calls will still return the same number.
3752
+ *
3753
+ * @param {Object} obj
3754
+ * @returns {number}
3755
+ */
3756
+ objId: function (obj) {
3757
+ if (!obj['__id']) {
3758
+ Object.defineProperty(obj, '__id', { value: ++uniqueId });
3759
+ }
3760
+ return obj['__id'];
3761
+ },
3620
3762
 
3621
- for (var key in o) {
3622
- if (o.hasOwnProperty(key)) {
3623
- clone[key] = deepClone(o[key], visited);
3763
+ /**
3764
+ * Creates a deep clone of the given object.
3765
+ *
3766
+ * The main intended use of this function is to clone language definitions.
3767
+ *
3768
+ * @param {T} o
3769
+ * @param {Record<number, any>} [visited]
3770
+ * @returns {T}
3771
+ * @template T
3772
+ */
3773
+ clone: function deepClone(o, visited) {
3774
+ visited = visited || {};
3775
+
3776
+ var clone; var id;
3777
+ switch (_.util.type(o)) {
3778
+ case 'Object':
3779
+ id = _.util.objId(o);
3780
+ if (visited[id]) {
3781
+ return visited[id];
3782
+ }
3783
+ clone = /** @type {Record<string, any>} */ ({});
3784
+ visited[id] = clone;
3785
+
3786
+ for (var key in o) {
3787
+ if (o.hasOwnProperty(key)) {
3788
+ clone[key] = deepClone(o[key], visited);
3789
+ }
3624
3790
  }
3625
- }
3626
3791
 
3627
- return /** @type {any} */ (clone);
3792
+ return /** @type {any} */ (clone);
3628
3793
 
3629
- case 'Array':
3630
- id = _.util.objId(o);
3631
- if (visited[id]) {
3632
- return visited[id];
3794
+ case 'Array':
3795
+ id = _.util.objId(o);
3796
+ if (visited[id]) {
3797
+ return visited[id];
3798
+ }
3799
+ clone = [];
3800
+ visited[id] = clone;
3801
+
3802
+ (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
3803
+ clone[i] = deepClone(v, visited);
3804
+ });
3805
+
3806
+ return /** @type {any} */ (clone);
3807
+
3808
+ default:
3809
+ return o;
3810
+ }
3811
+ },
3812
+
3813
+ /**
3814
+ * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
3815
+ *
3816
+ * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
3817
+ *
3818
+ * @param {Element} element
3819
+ * @returns {string}
3820
+ */
3821
+ getLanguage: function (element) {
3822
+ while (element) {
3823
+ var m = lang.exec(element.className);
3824
+ if (m) {
3825
+ return m[1].toLowerCase();
3633
3826
  }
3634
- clone = [];
3635
- visited[id] = clone;
3827
+ element = element.parentElement;
3828
+ }
3829
+ return 'none';
3830
+ },
3831
+
3832
+ /**
3833
+ * Sets the Prism `language-xxxx` class of the given element.
3834
+ *
3835
+ * @param {Element} element
3836
+ * @param {string} language
3837
+ * @returns {void}
3838
+ */
3839
+ setLanguage: function (element, language) {
3840
+ // remove all `language-xxxx` classes
3841
+ // (this might leave behind a leading space)
3842
+ element.className = element.className.replace(RegExp(lang, 'gi'), '');
3843
+
3844
+ // add the new `language-xxxx` class
3845
+ // (using `classList` will automatically clean up spaces for us)
3846
+ element.classList.add('language-' + language);
3847
+ },
3636
3848
 
3637
- (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
3638
- clone[i] = deepClone(v, visited);
3639
- });
3849
+ /**
3850
+ * Returns the script element that is currently executing.
3851
+ *
3852
+ * This does __not__ work for line script element.
3853
+ *
3854
+ * @returns {HTMLScriptElement | null}
3855
+ */
3856
+ currentScript: function () {
3857
+ if (typeof document === 'undefined') {
3858
+ return null;
3859
+ }
3860
+ if (document.currentScript && document.currentScript.tagName === 'SCRIPT' && 1 < 2 /* hack to trip TS' flow analysis */) {
3861
+ return /** @type {any} */ (document.currentScript);
3862
+ }
3640
3863
 
3641
- return /** @type {any} */ (clone);
3864
+ // IE11 workaround
3865
+ // we'll get the src of the current script by parsing IE11's error stack trace
3866
+ // this will not work for inline scripts
3867
+
3868
+ try {
3869
+ throw new Error();
3870
+ } catch (err) {
3871
+ // Get file src url from stack. Specifically works with the format of stack traces in IE.
3872
+ // A stack will look like this:
3873
+ //
3874
+ // Error
3875
+ // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
3876
+ // at Global code (http://localhost/components/prism-core.js:606:1)
3877
+
3878
+ var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) || [])[1];
3879
+ if (src) {
3880
+ var scripts = document.getElementsByTagName('script');
3881
+ for (var i in scripts) {
3882
+ if (scripts[i].src == src) {
3883
+ return scripts[i];
3884
+ }
3885
+ }
3886
+ }
3887
+ return null;
3888
+ }
3889
+ },
3642
3890
 
3643
- default:
3644
- return o;
3891
+ /**
3892
+ * Returns whether a given class is active for `element`.
3893
+ *
3894
+ * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
3895
+ * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
3896
+ * given class is just the given class with a `no-` prefix.
3897
+ *
3898
+ * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
3899
+ * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
3900
+ * ancestors have the given class or the negated version of it, then the default activation will be returned.
3901
+ *
3902
+ * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
3903
+ * version of it, the class is considered active.
3904
+ *
3905
+ * @param {Element} element
3906
+ * @param {string} className
3907
+ * @param {boolean} [defaultActivation=false]
3908
+ * @returns {boolean}
3909
+ */
3910
+ isActive: function (element, className, defaultActivation) {
3911
+ var no = 'no-' + className;
3912
+
3913
+ while (element) {
3914
+ var classList = element.classList;
3915
+ if (classList.contains(className)) {
3916
+ return true;
3917
+ }
3918
+ if (classList.contains(no)) {
3919
+ return false;
3920
+ }
3921
+ element = element.parentElement;
3922
+ }
3923
+ return !!defaultActivation;
3645
3924
  }
3646
3925
  },
3647
3926
 
3648
3927
  /**
3649
- * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
3650
- *
3651
- * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
3928
+ * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
3652
3929
  *
3653
- * @param {Element} element
3654
- * @returns {string}
3930
+ * @namespace
3931
+ * @memberof Prism
3932
+ * @public
3655
3933
  */
3656
- getLanguage: function (element) {
3657
- while (element) {
3658
- var m = lang.exec(element.className);
3659
- if (m) {
3660
- return m[1].toLowerCase();
3934
+ languages: {
3935
+ /**
3936
+ * The grammar for plain, unformatted text.
3937
+ */
3938
+ plain: plainTextGrammar,
3939
+ plaintext: plainTextGrammar,
3940
+ text: plainTextGrammar,
3941
+ txt: plainTextGrammar,
3942
+
3943
+ /**
3944
+ * Creates a deep copy of the language with the given id and appends the given tokens.
3945
+ *
3946
+ * If a token in `redef` also appears in the copied language, then the existing token in the copied language
3947
+ * will be overwritten at its original position.
3948
+ *
3949
+ * ## Best practices
3950
+ *
3951
+ * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
3952
+ * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
3953
+ * understand the language definition because, normally, the order of tokens matters in Prism grammars.
3954
+ *
3955
+ * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
3956
+ * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
3957
+ *
3958
+ * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
3959
+ * @param {Grammar} redef The new tokens to append.
3960
+ * @returns {Grammar} The new language created.
3961
+ * @public
3962
+ * @example
3963
+ * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
3964
+ * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
3965
+ * // at its original position
3966
+ * 'comment': { ... },
3967
+ * // CSS doesn't have a 'color' token, so this token will be appended
3968
+ * 'color': /\b(?:red|green|blue)\b/
3969
+ * });
3970
+ */
3971
+ extend: function (id, redef) {
3972
+ var lang = _.util.clone(_.languages[id]);
3973
+
3974
+ for (var key in redef) {
3975
+ lang[key] = redef[key];
3976
+ }
3977
+
3978
+ return lang;
3979
+ },
3980
+
3981
+ /**
3982
+ * Inserts tokens _before_ another token in a language definition or any other grammar.
3983
+ *
3984
+ * ## Usage
3985
+ *
3986
+ * This helper method makes it easy to modify existing languages. For example, the CSS language definition
3987
+ * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
3988
+ * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
3989
+ * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
3990
+ * this:
3991
+ *
3992
+ * ```js
3993
+ * Prism.languages.markup.style = {
3994
+ * // token
3995
+ * };
3996
+ * ```
3997
+ *
3998
+ * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
3999
+ * before existing tokens. For the CSS example above, you would use it like this:
4000
+ *
4001
+ * ```js
4002
+ * Prism.languages.insertBefore('markup', 'cdata', {
4003
+ * 'style': {
4004
+ * // token
4005
+ * }
4006
+ * });
4007
+ * ```
4008
+ *
4009
+ * ## Special cases
4010
+ *
4011
+ * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
4012
+ * will be ignored.
4013
+ *
4014
+ * This behavior can be used to insert tokens after `before`:
4015
+ *
4016
+ * ```js
4017
+ * Prism.languages.insertBefore('markup', 'comment', {
4018
+ * 'comment': Prism.languages.markup.comment,
4019
+ * // tokens after 'comment'
4020
+ * });
4021
+ * ```
4022
+ *
4023
+ * ## Limitations
4024
+ *
4025
+ * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
4026
+ * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
4027
+ * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
4028
+ * deleting properties which is necessary to insert at arbitrary positions.
4029
+ *
4030
+ * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
4031
+ * Instead, it will create a new object and replace all references to the target object with the new one. This
4032
+ * can be done without temporarily deleting properties, so the iteration order is well-defined.
4033
+ *
4034
+ * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
4035
+ * you hold the target object in a variable, then the value of the variable will not change.
4036
+ *
4037
+ * ```js
4038
+ * var oldMarkup = Prism.languages.markup;
4039
+ * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
4040
+ *
4041
+ * assert(oldMarkup !== Prism.languages.markup);
4042
+ * assert(newMarkup === Prism.languages.markup);
4043
+ * ```
4044
+ *
4045
+ * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
4046
+ * object to be modified.
4047
+ * @param {string} before The key to insert before.
4048
+ * @param {Grammar} insert An object containing the key-value pairs to be inserted.
4049
+ * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
4050
+ * object to be modified.
4051
+ *
4052
+ * Defaults to `Prism.languages`.
4053
+ * @returns {Grammar} The new grammar object.
4054
+ * @public
4055
+ */
4056
+ insertBefore: function (inside, before, insert, root) {
4057
+ root = root || /** @type {any} */ (_.languages);
4058
+ var grammar = root[inside];
4059
+ /** @type {Grammar} */
4060
+ var ret = {};
4061
+
4062
+ for (var token in grammar) {
4063
+ if (grammar.hasOwnProperty(token)) {
4064
+
4065
+ if (token == before) {
4066
+ for (var newToken in insert) {
4067
+ if (insert.hasOwnProperty(newToken)) {
4068
+ ret[newToken] = insert[newToken];
4069
+ }
4070
+ }
4071
+ }
4072
+
4073
+ // Do not insert token which also occur in insert. See #1525
4074
+ if (!insert.hasOwnProperty(token)) {
4075
+ ret[token] = grammar[token];
4076
+ }
4077
+ }
4078
+ }
4079
+
4080
+ var old = root[inside];
4081
+ root[inside] = ret;
4082
+
4083
+ // Update references in other language definitions
4084
+ _.languages.DFS(_.languages, function (key, value) {
4085
+ if (value === old && key != inside) {
4086
+ this[key] = ret;
4087
+ }
4088
+ });
4089
+
4090
+ return ret;
4091
+ },
4092
+
4093
+ // Traverse a language definition with Depth First Search
4094
+ DFS: function DFS(o, callback, type, visited) {
4095
+ visited = visited || {};
4096
+
4097
+ var objId = _.util.objId;
4098
+
4099
+ for (var i in o) {
4100
+ if (o.hasOwnProperty(i)) {
4101
+ callback.call(o, i, o[i], type || i);
4102
+
4103
+ var property = o[i];
4104
+ var propertyType = _.util.type(property);
4105
+
4106
+ if (propertyType === 'Object' && !visited[objId(property)]) {
4107
+ visited[objId(property)] = true;
4108
+ DFS(property, callback, null, visited);
4109
+ } else if (propertyType === 'Array' && !visited[objId(property)]) {
4110
+ visited[objId(property)] = true;
4111
+ DFS(property, callback, i, visited);
4112
+ }
4113
+ }
3661
4114
  }
3662
- element = element.parentElement;
3663
4115
  }
3664
- return 'none';
3665
4116
  },
3666
4117
 
4118
+ plugins: {},
4119
+
3667
4120
  /**
3668
- * Sets the Prism `language-xxxx` class of the given element.
4121
+ * This is the most high-level function in Prism’s API.
4122
+ * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
4123
+ * each one of them.
3669
4124
  *
3670
- * @param {Element} element
3671
- * @param {string} language
3672
- * @returns {void}
4125
+ * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
4126
+ *
4127
+ * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
4128
+ * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
4129
+ * @memberof Prism
4130
+ * @public
3673
4131
  */
3674
- setLanguage: function (element, language) {
3675
- // remove all `language-xxxx` classes
3676
- // (this might leave behind a leading space)
3677
- element.className = element.className.replace(RegExp(lang, 'gi'), '');
3678
-
3679
- // add the new `language-xxxx` class
3680
- // (using `classList` will automatically clean up spaces for us)
3681
- element.classList.add('language-' + language);
4132
+ highlightAll: function (async, callback) {
4133
+ _.highlightAllUnder(document, async, callback);
3682
4134
  },
3683
4135
 
3684
4136
  /**
3685
- * Returns the script element that is currently executing.
4137
+ * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
4138
+ * {@link Prism.highlightElement} on each one of them.
3686
4139
  *
3687
- * This does __not__ work for line script element.
4140
+ * The following hooks will be run:
4141
+ * 1. `before-highlightall`
4142
+ * 2. `before-all-elements-highlight`
4143
+ * 3. All hooks of {@link Prism.highlightElement} for each element.
3688
4144
  *
3689
- * @returns {HTMLScriptElement | null}
4145
+ * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
4146
+ * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
4147
+ * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
4148
+ * @memberof Prism
4149
+ * @public
3690
4150
  */
3691
- currentScript: function () {
3692
- if (typeof document === 'undefined') {
3693
- return null;
3694
- }
3695
- if (document.currentScript && document.currentScript.tagName === 'SCRIPT' && 1 < 2 /* hack to trip TS' flow analysis */) {
3696
- return /** @type {any} */ (document.currentScript);
3697
- }
4151
+ highlightAllUnder: function (container, async, callback) {
4152
+ var env = {
4153
+ callback: callback,
4154
+ container: container,
4155
+ selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
4156
+ };
3698
4157
 
3699
- // IE11 workaround
3700
- // we'll get the src of the current script by parsing IE11's error stack trace
3701
- // this will not work for inline scripts
3702
-
3703
- try {
3704
- throw new Error();
3705
- } catch (err) {
3706
- // Get file src url from stack. Specifically works with the format of stack traces in IE.
3707
- // A stack will look like this:
3708
- //
3709
- // Error
3710
- // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
3711
- // at Global code (http://localhost/components/prism-core.js:606:1)
3712
-
3713
- var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) || [])[1];
3714
- if (src) {
3715
- var scripts = document.getElementsByTagName('script');
3716
- for (var i in scripts) {
3717
- if (scripts[i].src == src) {
3718
- return scripts[i];
3719
- }
3720
- }
3721
- }
3722
- return null;
4158
+ _.hooks.run('before-highlightall', env);
4159
+
4160
+ env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
4161
+
4162
+ _.hooks.run('before-all-elements-highlight', env);
4163
+
4164
+ for (var i = 0, element; (element = env.elements[i++]);) {
4165
+ _.highlightElement(element, async === true, env.callback);
3723
4166
  }
3724
4167
  },
3725
4168
 
3726
4169
  /**
3727
- * Returns whether a given class is active for `element`.
4170
+ * Highlights the code inside a single element.
3728
4171
  *
3729
- * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
3730
- * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
3731
- * given class is just the given class with a `no-` prefix.
4172
+ * The following hooks will be run:
4173
+ * 1. `before-sanity-check`
4174
+ * 2. `before-highlight`
4175
+ * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
4176
+ * 4. `before-insert`
4177
+ * 5. `after-highlight`
4178
+ * 6. `complete`
3732
4179
  *
3733
- * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
3734
- * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
3735
- * ancestors have the given class or the negated version of it, then the default activation will be returned.
4180
+ * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
4181
+ * the element's language.
3736
4182
  *
3737
- * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
3738
- * version of it, the class is considered active.
4183
+ * @param {Element} element The element containing the code.
4184
+ * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
4185
+ * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
4186
+ * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
4187
+ * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
3739
4188
  *
3740
- * @param {Element} element
3741
- * @param {string} className
3742
- * @param {boolean} [defaultActivation=false]
3743
- * @returns {boolean}
4189
+ * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
4190
+ * asynchronous highlighting to work. You can build your own bundle on the
4191
+ * [Download page](https://prismjs.com/download.html).
4192
+ * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
4193
+ * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
4194
+ * @memberof Prism
4195
+ * @public
3744
4196
  */
3745
- isActive: function (element, className, defaultActivation) {
3746
- var no = 'no-' + className;
4197
+ highlightElement: function (element, async, callback) {
4198
+ // Find language
4199
+ var language = _.util.getLanguage(element);
4200
+ var grammar = _.languages[language];
4201
+
4202
+ // Set language on the element, if not present
4203
+ _.util.setLanguage(element, language);
4204
+
4205
+ // Set language on the parent, for styling
4206
+ var parent = element.parentElement;
4207
+ if (parent && parent.nodeName.toLowerCase() === 'pre') {
4208
+ _.util.setLanguage(parent, language);
4209
+ }
3747
4210
 
3748
- while (element) {
3749
- var classList = element.classList;
3750
- if (classList.contains(className)) {
3751
- return true;
3752
- }
3753
- if (classList.contains(no)) {
3754
- return false;
3755
- }
3756
- element = element.parentElement;
4211
+ var code = element.textContent;
4212
+
4213
+ var env = {
4214
+ element: element,
4215
+ language: language,
4216
+ grammar: grammar,
4217
+ code: code
4218
+ };
4219
+
4220
+ function insertHighlightedCode(highlightedCode) {
4221
+ env.highlightedCode = highlightedCode;
4222
+
4223
+ _.hooks.run('before-insert', env);
4224
+
4225
+ env.element.innerHTML = env.highlightedCode;
4226
+
4227
+ _.hooks.run('after-highlight', env);
4228
+ _.hooks.run('complete', env);
4229
+ callback && callback.call(env.element);
3757
4230
  }
3758
- return !!defaultActivation;
3759
- }
3760
- },
3761
4231
 
3762
- /**
3763
- * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
3764
- *
3765
- * @namespace
3766
- * @memberof Prism
3767
- * @public
3768
- */
3769
- languages: {
3770
- /**
3771
- * The grammar for plain, unformatted text.
3772
- */
3773
- plain: plainTextGrammar,
3774
- plaintext: plainTextGrammar,
3775
- text: plainTextGrammar,
3776
- txt: plainTextGrammar,
4232
+ _.hooks.run('before-sanity-check', env);
4233
+
4234
+ // plugins may change/add the parent/element
4235
+ parent = env.element.parentElement;
4236
+ if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
4237
+ parent.setAttribute('tabindex', '0');
4238
+ }
4239
+
4240
+ if (!env.code) {
4241
+ _.hooks.run('complete', env);
4242
+ callback && callback.call(env.element);
4243
+ return;
4244
+ }
4245
+
4246
+ _.hooks.run('before-highlight', env);
4247
+
4248
+ if (!env.grammar) {
4249
+ insertHighlightedCode(_.util.encode(env.code));
4250
+ return;
4251
+ }
4252
+
4253
+ if (async && _self.Worker) {
4254
+ var worker = new Worker(_.filename);
4255
+
4256
+ worker.onmessage = function (evt) {
4257
+ insertHighlightedCode(evt.data);
4258
+ };
4259
+
4260
+ worker.postMessage(JSON.stringify({
4261
+ language: env.language,
4262
+ code: env.code,
4263
+ immediateClose: true
4264
+ }));
4265
+ } else {
4266
+ insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
4267
+ }
4268
+ },
3777
4269
 
3778
4270
  /**
3779
- * Creates a deep copy of the language with the given id and appends the given tokens.
3780
- *
3781
- * If a token in `redef` also appears in the copied language, then the existing token in the copied language
3782
- * will be overwritten at its original position.
4271
+ * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
4272
+ * and the language definitions to use, and returns a string with the HTML produced.
3783
4273
  *
3784
- * ## Best practices
4274
+ * The following hooks will be run:
4275
+ * 1. `before-tokenize`
4276
+ * 2. `after-tokenize`
4277
+ * 3. `wrap`: On each {@link Token}.
3785
4278
  *
3786
- * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
3787
- * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
3788
- * understand the language definition because, normally, the order of tokens matters in Prism grammars.
4279
+ * @param {string} text A string with the code to be highlighted.
4280
+ * @param {Grammar} grammar An object containing the tokens to use.
3789
4281
  *
3790
- * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
3791
- * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
3792
- *
3793
- * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
3794
- * @param {Grammar} redef The new tokens to append.
3795
- * @returns {Grammar} The new language created.
4282
+ * Usually a language definition like `Prism.languages.markup`.
4283
+ * @param {string} language The name of the language definition passed to `grammar`.
4284
+ * @returns {string} The highlighted HTML.
4285
+ * @memberof Prism
3796
4286
  * @public
3797
4287
  * @example
3798
- * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
3799
- * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
3800
- * // at its original position
3801
- * 'comment': { ... },
3802
- * // CSS doesn't have a 'color' token, so this token will be appended
3803
- * 'color': /\b(?:red|green|blue)\b/
3804
- * });
4288
+ * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
3805
4289
  */
3806
- extend: function (id, redef) {
3807
- var lang = _.util.clone(_.languages[id]);
3808
-
3809
- for (var key in redef) {
3810
- lang[key] = redef[key];
4290
+ highlight: function (text, grammar, language) {
4291
+ var env = {
4292
+ code: text,
4293
+ grammar: grammar,
4294
+ language: language
4295
+ };
4296
+ _.hooks.run('before-tokenize', env);
4297
+ if (!env.grammar) {
4298
+ throw new Error('The language "' + env.language + '" has no grammar.');
3811
4299
  }
3812
-
3813
- return lang;
4300
+ env.tokens = _.tokenize(env.code, env.grammar);
4301
+ _.hooks.run('after-tokenize', env);
4302
+ return Token.stringify(_.util.encode(env.tokens), env.language);
3814
4303
  },
3815
4304
 
3816
4305
  /**
3817
- * Inserts tokens _before_ another token in a language definition or any other grammar.
3818
- *
3819
- * ## Usage
4306
+ * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
4307
+ * and the language definitions to use, and returns an array with the tokenized code.
3820
4308
  *
3821
- * This helper method makes it easy to modify existing languages. For example, the CSS language definition
3822
- * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
3823
- * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
3824
- * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
3825
- * this:
4309
+ * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
3826
4310
  *
3827
- * ```js
3828
- * Prism.languages.markup.style = {
3829
- * // token
3830
- * };
3831
- * ```
4311
+ * This method could be useful in other contexts as well, as a very crude parser.
3832
4312
  *
3833
- * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
3834
- * before existing tokens. For the CSS example above, you would use it like this:
4313
+ * @param {string} text A string with the code to be highlighted.
4314
+ * @param {Grammar} grammar An object containing the tokens to use.
3835
4315
  *
3836
- * ```js
3837
- * Prism.languages.insertBefore('markup', 'cdata', {
3838
- * 'style': {
3839
- * // token
4316
+ * Usually a language definition like `Prism.languages.markup`.
4317
+ * @returns {TokenStream} An array of strings and tokens, a token stream.
4318
+ * @memberof Prism
4319
+ * @public
4320
+ * @example
4321
+ * let code = `var foo = 0;`;
4322
+ * let tokens = Prism.tokenize(code, Prism.languages.javascript);
4323
+ * tokens.forEach(token => {
4324
+ * if (token instanceof Prism.Token && token.type === 'number') {
4325
+ * console.log(`Found numeric literal: ${token.content}`);
3840
4326
  * }
3841
4327
  * });
3842
- * ```
3843
- *
3844
- * ## Special cases
3845
- *
3846
- * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
3847
- * will be ignored.
3848
- *
3849
- * This behavior can be used to insert tokens after `before`:
3850
- *
3851
- * ```js
3852
- * Prism.languages.insertBefore('markup', 'comment', {
3853
- * 'comment': Prism.languages.markup.comment,
3854
- * // tokens after 'comment'
3855
- * });
3856
- * ```
3857
- *
3858
- * ## Limitations
3859
- *
3860
- * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
3861
- * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
3862
- * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
3863
- * deleting properties which is necessary to insert at arbitrary positions.
3864
- *
3865
- * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
3866
- * Instead, it will create a new object and replace all references to the target object with the new one. This
3867
- * can be done without temporarily deleting properties, so the iteration order is well-defined.
3868
- *
3869
- * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
3870
- * you hold the target object in a variable, then the value of the variable will not change.
3871
- *
3872
- * ```js
3873
- * var oldMarkup = Prism.languages.markup;
3874
- * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
3875
- *
3876
- * assert(oldMarkup !== Prism.languages.markup);
3877
- * assert(newMarkup === Prism.languages.markup);
3878
- * ```
3879
- *
3880
- * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
3881
- * object to be modified.
3882
- * @param {string} before The key to insert before.
3883
- * @param {Grammar} insert An object containing the key-value pairs to be inserted.
3884
- * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
3885
- * object to be modified.
3886
- *
3887
- * Defaults to `Prism.languages`.
3888
- * @returns {Grammar} The new grammar object.
3889
- * @public
3890
4328
  */
3891
- insertBefore: function (inside, before, insert, root) {
3892
- root = root || /** @type {any} */ (_.languages);
3893
- var grammar = root[inside];
3894
- /** @type {Grammar} */
3895
- var ret = {};
3896
-
3897
- for (var token in grammar) {
3898
- if (grammar.hasOwnProperty(token)) {
3899
-
3900
- if (token == before) {
3901
- for (var newToken in insert) {
3902
- if (insert.hasOwnProperty(newToken)) {
3903
- ret[newToken] = insert[newToken];
3904
- }
3905
- }
3906
- }
3907
-
3908
- // Do not insert token which also occur in insert. See #1525
3909
- if (!insert.hasOwnProperty(token)) {
3910
- ret[token] = grammar[token];
3911
- }
4329
+ tokenize: function (text, grammar) {
4330
+ var rest = grammar.rest;
4331
+ if (rest) {
4332
+ for (var token in rest) {
4333
+ grammar[token] = rest[token];
3912
4334
  }
4335
+
4336
+ delete grammar.rest;
3913
4337
  }
3914
4338
 
3915
- var old = root[inside];
3916
- root[inside] = ret;
4339
+ var tokenList = new LinkedList();
4340
+ addAfter(tokenList, tokenList.head, text);
3917
4341
 
3918
- // Update references in other language definitions
3919
- _.languages.DFS(_.languages, function (key, value) {
3920
- if (value === old && key != inside) {
3921
- this[key] = ret;
3922
- }
3923
- });
4342
+ matchGrammar(text, tokenList, grammar, tokenList.head, 0);
3924
4343
 
3925
- return ret;
4344
+ return toArray(tokenList);
3926
4345
  },
3927
4346
 
3928
- // Traverse a language definition with Depth First Search
3929
- DFS: function DFS(o, callback, type, visited) {
3930
- visited = visited || {};
3931
-
3932
- var objId = _.util.objId;
3933
-
3934
- for (var i in o) {
3935
- if (o.hasOwnProperty(i)) {
3936
- callback.call(o, i, o[i], type || i);
4347
+ /**
4348
+ * @namespace
4349
+ * @memberof Prism
4350
+ * @public
4351
+ */
4352
+ hooks: {
4353
+ all: {},
4354
+
4355
+ /**
4356
+ * Adds the given callback to the list of callbacks for the given hook.
4357
+ *
4358
+ * The callback will be invoked when the hook it is registered for is run.
4359
+ * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
4360
+ *
4361
+ * One callback function can be registered to multiple hooks and the same hook multiple times.
4362
+ *
4363
+ * @param {string} name The name of the hook.
4364
+ * @param {HookCallback} callback The callback function which is given environment variables.
4365
+ * @public
4366
+ */
4367
+ add: function (name, callback) {
4368
+ var hooks = _.hooks.all;
4369
+
4370
+ hooks[name] = hooks[name] || [];
4371
+
4372
+ hooks[name].push(callback);
4373
+ },
3937
4374
 
3938
- var property = o[i];
3939
- var propertyType = _.util.type(property);
4375
+ /**
4376
+ * Runs a hook invoking all registered callbacks with the given environment variables.
4377
+ *
4378
+ * Callbacks will be invoked synchronously and in the order in which they were registered.
4379
+ *
4380
+ * @param {string} name The name of the hook.
4381
+ * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
4382
+ * @public
4383
+ */
4384
+ run: function (name, env) {
4385
+ var callbacks = _.hooks.all[name];
4386
+
4387
+ if (!callbacks || !callbacks.length) {
4388
+ return;
4389
+ }
3940
4390
 
3941
- if (propertyType === 'Object' && !visited[objId(property)]) {
3942
- visited[objId(property)] = true;
3943
- DFS(property, callback, null, visited);
3944
- } else if (propertyType === 'Array' && !visited[objId(property)]) {
3945
- visited[objId(property)] = true;
3946
- DFS(property, callback, i, visited);
3947
- }
4391
+ for (var i = 0, callback; (callback = callbacks[i++]);) {
4392
+ callback(env);
3948
4393
  }
3949
4394
  }
3950
- }
3951
- },
4395
+ },
3952
4396
 
3953
- plugins: {},
4397
+ Token: Token
4398
+ };
4399
+ _self.Prism = _;
3954
4400
 
3955
- /**
3956
- * This is the most high-level function in Prism’s API.
3957
- * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
3958
- * each one of them.
3959
- *
3960
- * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
3961
- *
3962
- * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
3963
- * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
3964
- * @memberof Prism
3965
- * @public
3966
- */
3967
- highlightAll: function (async, callback) {
3968
- _.highlightAllUnder(document, async, callback);
3969
- },
3970
-
3971
- /**
3972
- * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
3973
- * {@link Prism.highlightElement} on each one of them.
3974
- *
3975
- * The following hooks will be run:
3976
- * 1. `before-highlightall`
3977
- * 2. `before-all-elements-highlight`
3978
- * 3. All hooks of {@link Prism.highlightElement} for each element.
3979
- *
3980
- * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
3981
- * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
3982
- * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
3983
- * @memberof Prism
3984
- * @public
3985
- */
3986
- highlightAllUnder: function (container, async, callback) {
3987
- var env = {
3988
- callback: callback,
3989
- container: container,
3990
- selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
3991
- };
3992
-
3993
- _.hooks.run('before-highlightall', env);
3994
-
3995
- env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
3996
-
3997
- _.hooks.run('before-all-elements-highlight', env);
3998
-
3999
- for (var i = 0, element; (element = env.elements[i++]);) {
4000
- _.highlightElement(element, async === true, env.callback);
4001
- }
4002
- },
4003
-
4004
- /**
4005
- * Highlights the code inside a single element.
4006
- *
4007
- * The following hooks will be run:
4008
- * 1. `before-sanity-check`
4009
- * 2. `before-highlight`
4010
- * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
4011
- * 4. `before-insert`
4012
- * 5. `after-highlight`
4013
- * 6. `complete`
4014
- *
4015
- * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
4016
- * the element's language.
4017
- *
4018
- * @param {Element} element The element containing the code.
4019
- * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
4020
- * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
4021
- * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
4022
- * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
4023
- *
4024
- * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
4025
- * asynchronous highlighting to work. You can build your own bundle on the
4026
- * [Download page](https://prismjs.com/download.html).
4027
- * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
4028
- * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
4029
- * @memberof Prism
4030
- * @public
4031
- */
4032
- highlightElement: function (element, async, callback) {
4033
- // Find language
4034
- var language = _.util.getLanguage(element);
4035
- var grammar = _.languages[language];
4036
-
4037
- // Set language on the element, if not present
4038
- _.util.setLanguage(element, language);
4039
-
4040
- // Set language on the parent, for styling
4041
- var parent = element.parentElement;
4042
- if (parent && parent.nodeName.toLowerCase() === 'pre') {
4043
- _.util.setLanguage(parent, language);
4044
- }
4045
-
4046
- var code = element.textContent;
4047
-
4048
- var env = {
4049
- element: element,
4050
- language: language,
4051
- grammar: grammar,
4052
- code: code
4053
- };
4054
-
4055
- function insertHighlightedCode(highlightedCode) {
4056
- env.highlightedCode = highlightedCode;
4057
-
4058
- _.hooks.run('before-insert', env);
4059
-
4060
- env.element.innerHTML = env.highlightedCode;
4061
-
4062
- _.hooks.run('after-highlight', env);
4063
- _.hooks.run('complete', env);
4064
- callback && callback.call(env.element);
4065
- }
4066
-
4067
- _.hooks.run('before-sanity-check', env);
4068
-
4069
- // plugins may change/add the parent/element
4070
- parent = env.element.parentElement;
4071
- if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
4072
- parent.setAttribute('tabindex', '0');
4073
- }
4074
-
4075
- if (!env.code) {
4076
- _.hooks.run('complete', env);
4077
- callback && callback.call(env.element);
4078
- return;
4079
- }
4080
-
4081
- _.hooks.run('before-highlight', env);
4082
-
4083
- if (!env.grammar) {
4084
- insertHighlightedCode(_.util.encode(env.code));
4085
- return;
4086
- }
4087
-
4088
- if (async && _self.Worker) {
4089
- var worker = new Worker(_.filename);
4090
-
4091
- worker.onmessage = function (evt) {
4092
- insertHighlightedCode(evt.data);
4093
- };
4094
-
4095
- worker.postMessage(JSON.stringify({
4096
- language: env.language,
4097
- code: env.code,
4098
- immediateClose: true
4099
- }));
4100
- } else {
4101
- insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
4102
- }
4103
- },
4104
4401
 
4105
- /**
4106
- * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
4107
- * and the language definitions to use, and returns a string with the HTML produced.
4108
- *
4109
- * The following hooks will be run:
4110
- * 1. `before-tokenize`
4111
- * 2. `after-tokenize`
4112
- * 3. `wrap`: On each {@link Token}.
4113
- *
4114
- * @param {string} text A string with the code to be highlighted.
4115
- * @param {Grammar} grammar An object containing the tokens to use.
4116
- *
4117
- * Usually a language definition like `Prism.languages.markup`.
4118
- * @param {string} language The name of the language definition passed to `grammar`.
4119
- * @returns {string} The highlighted HTML.
4120
- * @memberof Prism
4121
- * @public
4122
- * @example
4123
- * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
4124
- */
4125
- highlight: function (text, grammar, language) {
4126
- var env = {
4127
- code: text,
4128
- grammar: grammar,
4129
- language: language
4130
- };
4131
- _.hooks.run('before-tokenize', env);
4132
- if (!env.grammar) {
4133
- throw new Error('The language "' + env.language + '" has no grammar.');
4134
- }
4135
- env.tokens = _.tokenize(env.code, env.grammar);
4136
- _.hooks.run('after-tokenize', env);
4137
- return Token.stringify(_.util.encode(env.tokens), env.language);
4138
- },
4402
+ // Typescript note:
4403
+ // The following can be used to import the Token type in JSDoc:
4404
+ //
4405
+ // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
4139
4406
 
4140
4407
  /**
4141
- * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
4142
- * and the language definitions to use, and returns an array with the tokenized code.
4143
- *
4144
- * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
4145
- *
4146
- * This method could be useful in other contexts as well, as a very crude parser.
4408
+ * Creates a new token.
4147
4409
  *
4148
- * @param {string} text A string with the code to be highlighted.
4149
- * @param {Grammar} grammar An object containing the tokens to use.
4150
- *
4151
- * Usually a language definition like `Prism.languages.markup`.
4152
- * @returns {TokenStream} An array of strings and tokens, a token stream.
4153
- * @memberof Prism
4154
- * @public
4155
- * @example
4156
- * let code = `var foo = 0;`;
4157
- * let tokens = Prism.tokenize(code, Prism.languages.javascript);
4158
- * tokens.forEach(token => {
4159
- * if (token instanceof Prism.Token && token.type === 'number') {
4160
- * console.log(`Found numeric literal: ${token.content}`);
4161
- * }
4162
- * });
4163
- */
4164
- tokenize: function (text, grammar) {
4165
- var rest = grammar.rest;
4166
- if (rest) {
4167
- for (var token in rest) {
4168
- grammar[token] = rest[token];
4169
- }
4170
-
4171
- delete grammar.rest;
4172
- }
4173
-
4174
- var tokenList = new LinkedList();
4175
- addAfter(tokenList, tokenList.head, text);
4176
-
4177
- matchGrammar(text, tokenList, grammar, tokenList.head, 0);
4178
-
4179
- return toArray(tokenList);
4180
- },
4181
-
4182
- /**
4183
- * @namespace
4184
- * @memberof Prism
4410
+ * @param {string} type See {@link Token#type type}
4411
+ * @param {string | TokenStream} content See {@link Token#content content}
4412
+ * @param {string|string[]} [alias] The alias(es) of the token.
4413
+ * @param {string} [matchedStr=""] A copy of the full string this token was created from.
4414
+ * @class
4415
+ * @global
4185
4416
  * @public
4186
4417
  */
4187
- hooks: {
4188
- all: {},
4189
-
4418
+ function Token(type, content, alias, matchedStr) {
4190
4419
  /**
4191
- * Adds the given callback to the list of callbacks for the given hook.
4420
+ * The type of the token.
4192
4421
  *
4193
- * The callback will be invoked when the hook it is registered for is run.
4194
- * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
4422
+ * This is usually the key of a pattern in a {@link Grammar}.
4195
4423
  *
4196
- * One callback function can be registered to multiple hooks and the same hook multiple times.
4197
- *
4198
- * @param {string} name The name of the hook.
4199
- * @param {HookCallback} callback The callback function which is given environment variables.
4424
+ * @type {string}
4425
+ * @see GrammarToken
4200
4426
  * @public
4201
4427
  */
4202
- add: function (name, callback) {
4203
- var hooks = _.hooks.all;
4204
-
4205
- hooks[name] = hooks[name] || [];
4206
-
4207
- hooks[name].push(callback);
4208
- },
4209
-
4428
+ this.type = type;
4210
4429
  /**
4211
- * Runs a hook invoking all registered callbacks with the given environment variables.
4430
+ * The strings or tokens contained by this token.
4212
4431
  *
4213
- * Callbacks will be invoked synchronously and in the order in which they were registered.
4432
+ * This will be a token stream if the pattern matched also defined an `inside` grammar.
4214
4433
  *
4215
- * @param {string} name The name of the hook.
4216
- * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
4434
+ * @type {string | TokenStream}
4217
4435
  * @public
4218
4436
  */
4219
- run: function (name, env) {
4220
- var callbacks = _.hooks.all[name];
4221
-
4222
- if (!callbacks || !callbacks.length) {
4223
- return;
4224
- }
4225
-
4226
- for (var i = 0, callback; (callback = callbacks[i++]);) {
4227
- callback(env);
4228
- }
4229
- }
4230
- },
4231
-
4232
- Token: Token
4233
- };
4234
- _self.Prism = _;
4235
-
4236
-
4237
- // Typescript note:
4238
- // The following can be used to import the Token type in JSDoc:
4239
- //
4240
- // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
4437
+ this.content = content;
4438
+ /**
4439
+ * The alias(es) of the token.
4440
+ *
4441
+ * @type {string|string[]}
4442
+ * @see GrammarToken
4443
+ * @public
4444
+ */
4445
+ this.alias = alias;
4446
+ // Copy of the full string this token was created from
4447
+ this.length = (matchedStr || '').length | 0;
4448
+ }
4241
4449
 
4242
- /**
4243
- * Creates a new token.
4244
- *
4245
- * @param {string} type See {@link Token#type type}
4246
- * @param {string | TokenStream} content See {@link Token#content content}
4247
- * @param {string|string[]} [alias] The alias(es) of the token.
4248
- * @param {string} [matchedStr=""] A copy of the full string this token was created from.
4249
- * @class
4250
- * @global
4251
- * @public
4252
- */
4253
- function Token(type, content, alias, matchedStr) {
4254
4450
  /**
4255
- * The type of the token.
4451
+ * A token stream is an array of strings and {@link Token Token} objects.
4256
4452
  *
4257
- * This is usually the key of a pattern in a {@link Grammar}.
4453
+ * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
4454
+ * them.
4258
4455
  *
4259
- * @type {string}
4260
- * @see GrammarToken
4261
- * @public
4262
- */
4263
- this.type = type;
4264
- /**
4265
- * The strings or tokens contained by this token.
4456
+ * 1. No adjacent strings.
4457
+ * 2. No empty strings.
4266
4458
  *
4267
- * This will be a token stream if the pattern matched also defined an `inside` grammar.
4459
+ * The only exception here is the token stream that only contains the empty string and nothing else.
4268
4460
  *
4269
- * @type {string | TokenStream}
4461
+ * @typedef {Array<string | Token>} TokenStream
4462
+ * @global
4270
4463
  * @public
4271
4464
  */
4272
- this.content = content;
4465
+
4273
4466
  /**
4274
- * The alias(es) of the token.
4467
+ * Converts the given token or token stream to an HTML representation.
4275
4468
  *
4276
- * @type {string|string[]}
4277
- * @see GrammarToken
4278
- * @public
4469
+ * The following hooks will be run:
4470
+ * 1. `wrap`: On each {@link Token}.
4471
+ *
4472
+ * @param {string | Token | TokenStream} o The token or token stream to be converted.
4473
+ * @param {string} language The name of current language.
4474
+ * @returns {string} The HTML representation of the token or token stream.
4475
+ * @memberof Token
4476
+ * @static
4279
4477
  */
4280
- this.alias = alias;
4281
- // Copy of the full string this token was created from
4282
- this.length = (matchedStr || '').length | 0;
4283
- }
4284
-
4285
- /**
4286
- * A token stream is an array of strings and {@link Token Token} objects.
4287
- *
4288
- * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
4289
- * them.
4290
- *
4291
- * 1. No adjacent strings.
4292
- * 2. No empty strings.
4293
- *
4294
- * The only exception here is the token stream that only contains the empty string and nothing else.
4295
- *
4296
- * @typedef {Array<string | Token>} TokenStream
4297
- * @global
4298
- * @public
4299
- */
4300
-
4301
- /**
4302
- * Converts the given token or token stream to an HTML representation.
4303
- *
4304
- * The following hooks will be run:
4305
- * 1. `wrap`: On each {@link Token}.
4306
- *
4307
- * @param {string | Token | TokenStream} o The token or token stream to be converted.
4308
- * @param {string} language The name of current language.
4309
- * @returns {string} The HTML representation of the token or token stream.
4310
- * @memberof Token
4311
- * @static
4312
- */
4313
- Token.stringify = function stringify(o, language) {
4314
- if (typeof o == 'string') {
4315
- return o;
4316
- }
4317
- if (Array.isArray(o)) {
4318
- var s = '';
4319
- o.forEach(function (e) {
4320
- s += stringify(e, language);
4321
- });
4322
- return s;
4323
- }
4324
-
4325
- var env = {
4326
- type: o.type,
4327
- content: stringify(o.content, language),
4328
- tag: 'span',
4329
- classes: ['token', o.type],
4330
- attributes: {},
4331
- language: language
4332
- };
4333
-
4334
- var aliases = o.alias;
4335
- if (aliases) {
4336
- if (Array.isArray(aliases)) {
4337
- Array.prototype.push.apply(env.classes, aliases);
4338
- } else {
4339
- env.classes.push(aliases);
4478
+ Token.stringify = function stringify(o, language) {
4479
+ if (typeof o == 'string') {
4480
+ return o;
4481
+ }
4482
+ if (Array.isArray(o)) {
4483
+ var s = '';
4484
+ o.forEach(function (e) {
4485
+ s += stringify(e, language);
4486
+ });
4487
+ return s;
4340
4488
  }
4341
- }
4342
-
4343
- _.hooks.run('wrap', env);
4344
4489
 
4345
- var attributes = '';
4346
- for (var name in env.attributes) {
4347
- attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
4348
- }
4490
+ var env = {
4491
+ type: o.type,
4492
+ content: stringify(o.content, language),
4493
+ tag: 'span',
4494
+ classes: ['token', o.type],
4495
+ attributes: {},
4496
+ language: language
4497
+ };
4349
4498
 
4350
- return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
4351
- };
4499
+ var aliases = o.alias;
4500
+ if (aliases) {
4501
+ if (Array.isArray(aliases)) {
4502
+ Array.prototype.push.apply(env.classes, aliases);
4503
+ } else {
4504
+ env.classes.push(aliases);
4505
+ }
4506
+ }
4352
4507
 
4353
- /**
4354
- * @param {RegExp} pattern
4355
- * @param {number} pos
4356
- * @param {string} text
4357
- * @param {boolean} lookbehind
4358
- * @returns {RegExpExecArray | null}
4359
- */
4360
- function matchPattern(pattern, pos, text, lookbehind) {
4361
- pattern.lastIndex = pos;
4362
- var match = pattern.exec(text);
4363
- if (match && lookbehind && match[1]) {
4364
- // change the match to remove the text matched by the Prism lookbehind group
4365
- var lookbehindLength = match[1].length;
4366
- match.index += lookbehindLength;
4367
- match[0] = match[0].slice(lookbehindLength);
4368
- }
4369
- return match;
4370
- }
4508
+ _.hooks.run('wrap', env);
4371
4509
 
4372
- /**
4373
- * @param {string} text
4374
- * @param {LinkedList<string | Token>} tokenList
4375
- * @param {any} grammar
4376
- * @param {LinkedListNode<string | Token>} startNode
4377
- * @param {number} startPos
4378
- * @param {RematchOptions} [rematch]
4379
- * @returns {void}
4380
- * @private
4381
- *
4382
- * @typedef RematchOptions
4383
- * @property {string} cause
4384
- * @property {number} reach
4385
- */
4386
- function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
4387
- for (var token in grammar) {
4388
- if (!grammar.hasOwnProperty(token) || !grammar[token]) {
4389
- continue;
4510
+ var attributes = '';
4511
+ for (var name in env.attributes) {
4512
+ attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
4390
4513
  }
4391
4514
 
4392
- var patterns = grammar[token];
4393
- patterns = Array.isArray(patterns) ? patterns : [patterns];
4394
-
4395
- for (var j = 0; j < patterns.length; ++j) {
4396
- if (rematch && rematch.cause == token + ',' + j) {
4397
- return;
4398
- }
4515
+ return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
4516
+ };
4399
4517
 
4400
- var patternObj = patterns[j];
4401
- var inside = patternObj.inside;
4402
- var lookbehind = !!patternObj.lookbehind;
4403
- var greedy = !!patternObj.greedy;
4404
- var alias = patternObj.alias;
4518
+ /**
4519
+ * @param {RegExp} pattern
4520
+ * @param {number} pos
4521
+ * @param {string} text
4522
+ * @param {boolean} lookbehind
4523
+ * @returns {RegExpExecArray | null}
4524
+ */
4525
+ function matchPattern(pattern, pos, text, lookbehind) {
4526
+ pattern.lastIndex = pos;
4527
+ var match = pattern.exec(text);
4528
+ if (match && lookbehind && match[1]) {
4529
+ // change the match to remove the text matched by the Prism lookbehind group
4530
+ var lookbehindLength = match[1].length;
4531
+ match.index += lookbehindLength;
4532
+ match[0] = match[0].slice(lookbehindLength);
4533
+ }
4534
+ return match;
4535
+ }
4405
4536
 
4406
- if (greedy && !patternObj.pattern.global) {
4407
- // Without the global flag, lastIndex won't work
4408
- var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
4409
- patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
4537
+ /**
4538
+ * @param {string} text
4539
+ * @param {LinkedList<string | Token>} tokenList
4540
+ * @param {any} grammar
4541
+ * @param {LinkedListNode<string | Token>} startNode
4542
+ * @param {number} startPos
4543
+ * @param {RematchOptions} [rematch]
4544
+ * @returns {void}
4545
+ * @private
4546
+ *
4547
+ * @typedef RematchOptions
4548
+ * @property {string} cause
4549
+ * @property {number} reach
4550
+ */
4551
+ function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
4552
+ for (var token in grammar) {
4553
+ if (!grammar.hasOwnProperty(token) || !grammar[token]) {
4554
+ continue;
4410
4555
  }
4411
4556
 
4412
- /** @type {RegExp} */
4413
- var pattern = patternObj.pattern || patternObj;
4557
+ var patterns = grammar[token];
4558
+ patterns = Array.isArray(patterns) ? patterns : [patterns];
4414
4559
 
4415
- for ( // iterate the token list and keep track of the current token/string position
4416
- var currentNode = startNode.next, pos = startPos;
4417
- currentNode !== tokenList.tail;
4418
- pos += currentNode.value.length, currentNode = currentNode.next
4419
- ) {
4420
-
4421
- if (rematch && pos >= rematch.reach) {
4422
- break;
4560
+ for (var j = 0; j < patterns.length; ++j) {
4561
+ if (rematch && rematch.cause == token + ',' + j) {
4562
+ return;
4423
4563
  }
4424
4564
 
4425
- var str = currentNode.value;
4565
+ var patternObj = patterns[j];
4566
+ var inside = patternObj.inside;
4567
+ var lookbehind = !!patternObj.lookbehind;
4568
+ var greedy = !!patternObj.greedy;
4569
+ var alias = patternObj.alias;
4426
4570
 
4427
- if (tokenList.length > text.length) {
4428
- // Something went terribly wrong, ABORT, ABORT!
4429
- return;
4571
+ if (greedy && !patternObj.pattern.global) {
4572
+ // Without the global flag, lastIndex won't work
4573
+ var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
4574
+ patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
4430
4575
  }
4431
4576
 
4432
- if (str instanceof Token) {
4433
- continue;
4434
- }
4577
+ /** @type {RegExp} */
4578
+ var pattern = patternObj.pattern || patternObj;
4435
4579
 
4436
- var removeCount = 1; // this is the to parameter of removeBetween
4437
- var match;
4580
+ for ( // iterate the token list and keep track of the current token/string position
4581
+ var currentNode = startNode.next, pos = startPos;
4582
+ currentNode !== tokenList.tail;
4583
+ pos += currentNode.value.length, currentNode = currentNode.next
4584
+ ) {
4438
4585
 
4439
- if (greedy) {
4440
- match = matchPattern(pattern, pos, text, lookbehind);
4441
- if (!match || match.index >= text.length) {
4586
+ if (rematch && pos >= rematch.reach) {
4442
4587
  break;
4443
4588
  }
4444
4589
 
4445
- var from = match.index;
4446
- var to = match.index + match[0].length;
4447
- var p = pos;
4590
+ var str = currentNode.value;
4448
4591
 
4449
- // find the node that contains the match
4450
- p += currentNode.value.length;
4451
- while (from >= p) {
4452
- currentNode = currentNode.next;
4453
- p += currentNode.value.length;
4592
+ if (tokenList.length > text.length) {
4593
+ // Something went terribly wrong, ABORT, ABORT!
4594
+ return;
4454
4595
  }
4455
- // adjust pos (and p)
4456
- p -= currentNode.value.length;
4457
- pos = p;
4458
4596
 
4459
- // the current node is a Token, then the match starts inside another Token, which is invalid
4460
- if (currentNode.value instanceof Token) {
4597
+ if (str instanceof Token) {
4461
4598
  continue;
4462
4599
  }
4463
4600
 
4464
- // find the last node which is affected by this match
4465
- for (
4466
- var k = currentNode;
4467
- k !== tokenList.tail && (p < to || typeof k.value === 'string');
4468
- k = k.next
4469
- ) {
4470
- removeCount++;
4471
- p += k.value.length;
4472
- }
4473
- removeCount--;
4601
+ var removeCount = 1; // this is the to parameter of removeBetween
4602
+ var match;
4474
4603
 
4475
- // replace with the new match
4476
- str = text.slice(pos, p);
4477
- match.index -= pos;
4478
- } else {
4479
- match = matchPattern(pattern, 0, str, lookbehind);
4480
- if (!match) {
4481
- continue;
4604
+ if (greedy) {
4605
+ match = matchPattern(pattern, pos, text, lookbehind);
4606
+ if (!match || match.index >= text.length) {
4607
+ break;
4608
+ }
4609
+
4610
+ var from = match.index;
4611
+ var to = match.index + match[0].length;
4612
+ var p = pos;
4613
+
4614
+ // find the node that contains the match
4615
+ p += currentNode.value.length;
4616
+ while (from >= p) {
4617
+ currentNode = currentNode.next;
4618
+ p += currentNode.value.length;
4619
+ }
4620
+ // adjust pos (and p)
4621
+ p -= currentNode.value.length;
4622
+ pos = p;
4623
+
4624
+ // the current node is a Token, then the match starts inside another Token, which is invalid
4625
+ if (currentNode.value instanceof Token) {
4626
+ continue;
4627
+ }
4628
+
4629
+ // find the last node which is affected by this match
4630
+ for (
4631
+ var k = currentNode;
4632
+ k !== tokenList.tail && (p < to || typeof k.value === 'string');
4633
+ k = k.next
4634
+ ) {
4635
+ removeCount++;
4636
+ p += k.value.length;
4637
+ }
4638
+ removeCount--;
4639
+
4640
+ // replace with the new match
4641
+ str = text.slice(pos, p);
4642
+ match.index -= pos;
4643
+ } else {
4644
+ match = matchPattern(pattern, 0, str, lookbehind);
4645
+ if (!match) {
4646
+ continue;
4647
+ }
4482
4648
  }
4483
- }
4484
4649
 
4485
- // eslint-disable-next-line no-redeclare
4486
- var from = match.index;
4487
- var matchStr = match[0];
4488
- var before = str.slice(0, from);
4489
- var after = str.slice(from + matchStr.length);
4650
+ // eslint-disable-next-line no-redeclare
4651
+ var from = match.index;
4652
+ var matchStr = match[0];
4653
+ var before = str.slice(0, from);
4654
+ var after = str.slice(from + matchStr.length);
4490
4655
 
4491
- var reach = pos + str.length;
4492
- if (rematch && reach > rematch.reach) {
4493
- rematch.reach = reach;
4494
- }
4656
+ var reach = pos + str.length;
4657
+ if (rematch && reach > rematch.reach) {
4658
+ rematch.reach = reach;
4659
+ }
4495
4660
 
4496
- var removeFrom = currentNode.prev;
4661
+ var removeFrom = currentNode.prev;
4497
4662
 
4498
- if (before) {
4499
- removeFrom = addAfter(tokenList, removeFrom, before);
4500
- pos += before.length;
4501
- }
4663
+ if (before) {
4664
+ removeFrom = addAfter(tokenList, removeFrom, before);
4665
+ pos += before.length;
4666
+ }
4502
4667
 
4503
- removeRange(tokenList, removeFrom, removeCount);
4668
+ removeRange(tokenList, removeFrom, removeCount);
4504
4669
 
4505
- var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
4506
- currentNode = addAfter(tokenList, removeFrom, wrapped);
4670
+ var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
4671
+ currentNode = addAfter(tokenList, removeFrom, wrapped);
4507
4672
 
4508
- if (after) {
4509
- addAfter(tokenList, currentNode, after);
4510
- }
4673
+ if (after) {
4674
+ addAfter(tokenList, currentNode, after);
4675
+ }
4511
4676
 
4512
- if (removeCount > 1) {
4513
- // at least one Token object was removed, so we have to do some rematching
4514
- // this can only happen if the current pattern is greedy
4677
+ if (removeCount > 1) {
4678
+ // at least one Token object was removed, so we have to do some rematching
4679
+ // this can only happen if the current pattern is greedy
4515
4680
 
4516
- /** @type {RematchOptions} */
4517
- var nestedRematch = {
4518
- cause: token + ',' + j,
4519
- reach: reach
4520
- };
4521
- matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
4681
+ /** @type {RematchOptions} */
4682
+ var nestedRematch = {
4683
+ cause: token + ',' + j,
4684
+ reach: reach
4685
+ };
4686
+ matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
4522
4687
 
4523
- // the reach might have been extended because of the rematching
4524
- if (rematch && nestedRematch.reach > rematch.reach) {
4525
- rematch.reach = nestedRematch.reach;
4688
+ // the reach might have been extended because of the rematching
4689
+ if (rematch && nestedRematch.reach > rematch.reach) {
4690
+ rematch.reach = nestedRematch.reach;
4691
+ }
4526
4692
  }
4527
4693
  }
4528
4694
  }
4529
4695
  }
4530
4696
  }
4531
- }
4532
4697
 
4533
- /**
4534
- * @typedef LinkedListNode
4535
- * @property {T} value
4536
- * @property {LinkedListNode<T> | null} prev The previous node.
4537
- * @property {LinkedListNode<T> | null} next The next node.
4538
- * @template T
4539
- * @private
4540
- */
4698
+ /**
4699
+ * @typedef LinkedListNode
4700
+ * @property {T} value
4701
+ * @property {LinkedListNode<T> | null} prev The previous node.
4702
+ * @property {LinkedListNode<T> | null} next The next node.
4703
+ * @template T
4704
+ * @private
4705
+ */
4541
4706
 
4542
- /**
4543
- * @template T
4544
- * @private
4545
- */
4546
- function LinkedList() {
4547
- /** @type {LinkedListNode<T>} */
4548
- var head = { value: null, prev: null, next: null };
4549
- /** @type {LinkedListNode<T>} */
4550
- var tail = { value: null, prev: head, next: null };
4551
- head.next = tail;
4552
-
4553
- /** @type {LinkedListNode<T>} */
4554
- this.head = head;
4555
- /** @type {LinkedListNode<T>} */
4556
- this.tail = tail;
4557
- this.length = 0;
4558
- }
4707
+ /**
4708
+ * @template T
4709
+ * @private
4710
+ */
4711
+ function LinkedList() {
4712
+ /** @type {LinkedListNode<T>} */
4713
+ var head = { value: null, prev: null, next: null };
4714
+ /** @type {LinkedListNode<T>} */
4715
+ var tail = { value: null, prev: head, next: null };
4716
+ head.next = tail;
4717
+
4718
+ /** @type {LinkedListNode<T>} */
4719
+ this.head = head;
4720
+ /** @type {LinkedListNode<T>} */
4721
+ this.tail = tail;
4722
+ this.length = 0;
4723
+ }
4559
4724
 
4560
- /**
4561
- * Adds a new node with the given value to the list.
4562
- *
4563
- * @param {LinkedList<T>} list
4564
- * @param {LinkedListNode<T>} node
4565
- * @param {T} value
4566
- * @returns {LinkedListNode<T>} The added node.
4567
- * @template T
4568
- */
4569
- function addAfter(list, node, value) {
4570
- // assumes that node != list.tail && values.length >= 0
4571
- var next = node.next;
4725
+ /**
4726
+ * Adds a new node with the given value to the list.
4727
+ *
4728
+ * @param {LinkedList<T>} list
4729
+ * @param {LinkedListNode<T>} node
4730
+ * @param {T} value
4731
+ * @returns {LinkedListNode<T>} The added node.
4732
+ * @template T
4733
+ */
4734
+ function addAfter(list, node, value) {
4735
+ // assumes that node != list.tail && values.length >= 0
4736
+ var next = node.next;
4572
4737
 
4573
- var newNode = { value: value, prev: node, next: next };
4574
- node.next = newNode;
4575
- next.prev = newNode;
4576
- list.length++;
4738
+ var newNode = { value: value, prev: node, next: next };
4739
+ node.next = newNode;
4740
+ next.prev = newNode;
4741
+ list.length++;
4577
4742
 
4578
- return newNode;
4579
- }
4580
- /**
4581
- * Removes `count` nodes after the given node. The given node will not be removed.
4582
- *
4583
- * @param {LinkedList<T>} list
4584
- * @param {LinkedListNode<T>} node
4585
- * @param {number} count
4586
- * @template T
4587
- */
4588
- function removeRange(list, node, count) {
4589
- var next = node.next;
4590
- for (var i = 0; i < count && next !== list.tail; i++) {
4591
- next = next.next;
4743
+ return newNode;
4592
4744
  }
4593
- node.next = next;
4594
- next.prev = node;
4595
- list.length -= i;
4596
- }
4597
- /**
4598
- * @param {LinkedList<T>} list
4599
- * @returns {T[]}
4600
- * @template T
4601
- */
4602
- function toArray(list) {
4603
- var array = [];
4604
- var node = list.head.next;
4605
- while (node !== list.tail) {
4606
- array.push(node.value);
4607
- node = node.next;
4745
+ /**
4746
+ * Removes `count` nodes after the given node. The given node will not be removed.
4747
+ *
4748
+ * @param {LinkedList<T>} list
4749
+ * @param {LinkedListNode<T>} node
4750
+ * @param {number} count
4751
+ * @template T
4752
+ */
4753
+ function removeRange(list, node, count) {
4754
+ var next = node.next;
4755
+ for (var i = 0; i < count && next !== list.tail; i++) {
4756
+ next = next.next;
4757
+ }
4758
+ node.next = next;
4759
+ next.prev = node;
4760
+ list.length -= i;
4761
+ }
4762
+ /**
4763
+ * @param {LinkedList<T>} list
4764
+ * @returns {T[]}
4765
+ * @template T
4766
+ */
4767
+ function toArray(list) {
4768
+ var array = [];
4769
+ var node = list.head.next;
4770
+ while (node !== list.tail) {
4771
+ array.push(node.value);
4772
+ node = node.next;
4773
+ }
4774
+ return array;
4608
4775
  }
4609
- return array;
4610
- }
4611
4776
 
4612
4777
 
4613
- if (!_self.document) {
4614
- if (!_self.addEventListener) {
4615
- // in Node.js
4616
- return _;
4617
- }
4778
+ if (!_self.document) {
4779
+ if (!_self.addEventListener) {
4780
+ // in Node.js
4781
+ return _;
4782
+ }
4618
4783
 
4619
- if (!_.disableWorkerMessageHandler) {
4620
- // In worker
4621
- _self.addEventListener('message', function (evt) {
4622
- var message = JSON.parse(evt.data);
4623
- var lang = message.language;
4624
- var code = message.code;
4625
- var immediateClose = message.immediateClose;
4626
-
4627
- _self.postMessage(_.highlight(code, _.languages[lang], lang));
4628
- if (immediateClose) {
4629
- _self.close();
4630
- }
4631
- }, false);
4632
- }
4784
+ if (!_.disableWorkerMessageHandler) {
4785
+ // In worker
4786
+ _self.addEventListener('message', function (evt) {
4787
+ var message = JSON.parse(evt.data);
4788
+ var lang = message.language;
4789
+ var code = message.code;
4790
+ var immediateClose = message.immediateClose;
4791
+
4792
+ _self.postMessage(_.highlight(code, _.languages[lang], lang));
4793
+ if (immediateClose) {
4794
+ _self.close();
4795
+ }
4796
+ }, false);
4797
+ }
4633
4798
 
4634
- return _;
4635
- }
4799
+ return _;
4800
+ }
4636
4801
 
4637
- // Get current script and highlight
4638
- var script = _.util.currentScript();
4802
+ // Get current script and highlight
4803
+ var script = _.util.currentScript();
4639
4804
 
4640
- if (script) {
4641
- _.filename = script.src;
4805
+ if (script) {
4806
+ _.filename = script.src;
4642
4807
 
4643
- if (script.hasAttribute('data-manual')) {
4644
- _.manual = true;
4808
+ if (script.hasAttribute('data-manual')) {
4809
+ _.manual = true;
4810
+ }
4645
4811
  }
4646
- }
4647
4812
 
4648
- function highlightAutomaticallyCallback() {
4649
- if (!_.manual) {
4650
- _.highlightAll();
4813
+ function highlightAutomaticallyCallback() {
4814
+ if (!_.manual) {
4815
+ _.highlightAll();
4816
+ }
4651
4817
  }
4652
- }
4653
4818
 
4654
- if (!_.manual) {
4655
- // If the document state is "loading", then we'll use DOMContentLoaded.
4656
- // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
4657
- // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
4658
- // might take longer one animation frame to execute which can create a race condition where only some plugins have
4659
- // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
4660
- // See https://github.com/PrismJS/prism/issues/2102
4661
- var readyState = document.readyState;
4662
- if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
4663
- document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
4664
- } else {
4665
- if (window.requestAnimationFrame) {
4666
- window.requestAnimationFrame(highlightAutomaticallyCallback);
4819
+ if (!_.manual) {
4820
+ // If the document state is "loading", then we'll use DOMContentLoaded.
4821
+ // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
4822
+ // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
4823
+ // might take longer one animation frame to execute which can create a race condition where only some plugins have
4824
+ // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
4825
+ // See https://github.com/PrismJS/prism/issues/2102
4826
+ var readyState = document.readyState;
4827
+ if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
4828
+ document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
4667
4829
  } else {
4668
- window.setTimeout(highlightAutomaticallyCallback, 16);
4830
+ if (window.requestAnimationFrame) {
4831
+ window.requestAnimationFrame(highlightAutomaticallyCallback);
4832
+ } else {
4833
+ window.setTimeout(highlightAutomaticallyCallback, 16);
4834
+ }
4669
4835
  }
4670
4836
  }
4671
- }
4672
4837
 
4673
- return _;
4838
+ return _;
4674
4839
 
4675
- }(_self));
4840
+ }(_self));
4676
4841
 
4677
- if (module.exports) {
4678
- module.exports = Prism;
4679
- }
4842
+ if (module.exports) {
4843
+ module.exports = Prism;
4844
+ }
4680
4845
 
4681
- // hack for components to work correctly in node.js
4682
- if (typeof commonjsGlobal !== 'undefined') {
4683
- commonjsGlobal.Prism = Prism;
4684
- }
4685
-
4686
- // some additional documentation/types
4687
-
4688
- /**
4689
- * The expansion of a simple `RegExp` literal to support additional properties.
4690
- *
4691
- * @typedef GrammarToken
4692
- * @property {RegExp} pattern The regular expression of the token.
4693
- * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
4694
- * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
4695
- * @property {boolean} [greedy=false] Whether the token is greedy.
4696
- * @property {string|string[]} [alias] An optional alias or list of aliases.
4697
- * @property {Grammar} [inside] The nested grammar of this token.
4698
- *
4699
- * The `inside` grammar will be used to tokenize the text value of each token of this kind.
4700
- *
4701
- * This can be used to make nested and even recursive language definitions.
4702
- *
4703
- * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
4704
- * each another.
4705
- * @global
4706
- * @public
4707
- */
4708
-
4709
- /**
4710
- * @typedef Grammar
4711
- * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
4712
- * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
4713
- * @global
4714
- * @public
4715
- */
4716
-
4717
- /**
4718
- * A function which will invoked after an element was successfully highlighted.
4719
- *
4720
- * @callback HighlightCallback
4721
- * @param {Element} element The element successfully highlighted.
4722
- * @returns {void}
4723
- * @global
4724
- * @public
4725
- */
4726
-
4727
- /**
4728
- * @callback HookCallback
4729
- * @param {Object<string, any>} env The environment variables of the hook.
4730
- * @returns {void}
4731
- * @global
4732
- * @public
4733
- */
4734
-
4735
-
4736
- /* **********************************************
4737
- Begin prism-markup.js
4738
- ********************************************** */
4739
-
4740
- Prism.languages.markup = {
4741
- 'comment': {
4742
- pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
4743
- greedy: true
4744
- },
4745
- 'prolog': {
4746
- pattern: /<\?[\s\S]+?\?>/,
4747
- greedy: true
4748
- },
4749
- 'doctype': {
4750
- // https://www.w3.org/TR/xml/#NT-doctypedecl
4751
- pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
4752
- greedy: true,
4753
- inside: {
4754
- 'internal-subset': {
4755
- pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
4756
- lookbehind: true,
4757
- greedy: true,
4758
- inside: null // see below
4759
- },
4760
- 'string': {
4761
- pattern: /"[^"]*"|'[^']*'/,
4762
- greedy: true
4763
- },
4764
- 'punctuation': /^<!|>$|[[\]]/,
4765
- 'doctype-tag': /^DOCTYPE/i,
4766
- 'name': /[^\s<>'"]+/
4767
- }
4768
- },
4769
- 'cdata': {
4770
- pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
4771
- greedy: true
4772
- },
4773
- 'tag': {
4774
- pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
4775
- greedy: true,
4776
- inside: {
4777
- 'tag': {
4778
- pattern: /^<\/?[^\s>\/]+/,
4779
- inside: {
4780
- 'punctuation': /^<\/?/,
4781
- 'namespace': /^[^\s>\/:]+:/
4782
- }
4783
- },
4784
- 'special-attr': [],
4785
- 'attr-value': {
4786
- pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
4787
- inside: {
4788
- 'punctuation': [
4789
- {
4790
- pattern: /^=/,
4791
- alias: 'attr-equals'
4792
- },
4793
- {
4794
- pattern: /^(\s*)["']|["']$/,
4795
- lookbehind: true
4796
- }
4797
- ]
4798
- }
4799
- },
4800
- 'punctuation': /\/?>/,
4801
- 'attr-name': {
4802
- pattern: /[^\s>\/]+/,
4803
- inside: {
4804
- 'namespace': /^[^\s>\/:]+:/
4805
- }
4806
- }
4807
-
4808
- }
4809
- },
4810
- 'entity': [
4811
- {
4812
- pattern: /&[\da-z]{1,8};/i,
4813
- alias: 'named-entity'
4814
- },
4815
- /&#x?[\da-f]{1,8};/i
4816
- ]
4817
- };
4818
-
4819
- Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
4820
- Prism.languages.markup['entity'];
4821
- Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
4822
-
4823
- // Plugin to make entity title show the real entity, idea by Roman Komarov
4824
- Prism.hooks.add('wrap', function (env) {
4825
-
4826
- if (env.type === 'entity') {
4827
- env.attributes['title'] = env.content.replace(/&amp;/, '&');
4846
+ // hack for components to work correctly in node.js
4847
+ if (typeof commonjsGlobal !== 'undefined') {
4848
+ commonjsGlobal.Prism = Prism;
4828
4849
  }
4829
- });
4830
4850
 
4831
- Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
4851
+ // some additional documentation/types
4852
+
4832
4853
  /**
4833
- * Adds an inlined language to markup.
4854
+ * The expansion of a simple `RegExp` literal to support additional properties.
4855
+ *
4856
+ * @typedef GrammarToken
4857
+ * @property {RegExp} pattern The regular expression of the token.
4858
+ * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
4859
+ * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
4860
+ * @property {boolean} [greedy=false] Whether the token is greedy.
4861
+ * @property {string|string[]} [alias] An optional alias or list of aliases.
4862
+ * @property {Grammar} [inside] The nested grammar of this token.
4834
4863
  *
4835
- * An example of an inlined language is CSS with `<style>` tags.
4864
+ * The `inside` grammar will be used to tokenize the text value of each token of this kind.
4836
4865
  *
4837
- * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
4838
- * case insensitive.
4839
- * @param {string} lang The language key.
4840
- * @example
4841
- * addInlined('style', 'css');
4866
+ * This can be used to make nested and even recursive language definitions.
4867
+ *
4868
+ * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
4869
+ * each another.
4870
+ * @global
4871
+ * @public
4842
4872
  */
4843
- value: function addInlined(tagName, lang) {
4844
- var includedCdataInside = {};
4845
- includedCdataInside['language-' + lang] = {
4846
- pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
4847
- lookbehind: true,
4848
- inside: Prism.languages[lang]
4849
- };
4850
- includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
4851
4873
 
4852
- var inside = {
4853
- 'included-cdata': {
4854
- pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
4855
- inside: includedCdataInside
4856
- }
4857
- };
4858
- inside['language-' + lang] = {
4859
- pattern: /[\s\S]+/,
4860
- inside: Prism.languages[lang]
4861
- };
4862
-
4863
- var def = {};
4864
- def[tagName] = {
4865
- pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
4866
- lookbehind: true,
4867
- greedy: true,
4868
- inside: inside
4869
- };
4874
+ /**
4875
+ * @typedef Grammar
4876
+ * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
4877
+ * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
4878
+ * @global
4879
+ * @public
4880
+ */
4870
4881
 
4871
- Prism.languages.insertBefore('markup', 'cdata', def);
4872
- }
4873
- });
4874
- Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
4875
4882
  /**
4876
- * Adds an pattern to highlight languages embedded in HTML attributes.
4877
- *
4878
- * An example of an inlined language is CSS with `style` attributes.
4883
+ * A function which will invoked after an element was successfully highlighted.
4879
4884
  *
4880
- * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
4881
- * case insensitive.
4882
- * @param {string} lang The language key.
4883
- * @example
4884
- * addAttribute('style', 'css');
4885
+ * @callback HighlightCallback
4886
+ * @param {Element} element The element successfully highlighted.
4887
+ * @returns {void}
4888
+ * @global
4889
+ * @public
4885
4890
  */
4886
- value: function (attrName, lang) {
4887
- Prism.languages.markup.tag.inside['special-attr'].push({
4888
- pattern: RegExp(
4889
- /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
4890
- 'i'
4891
- ),
4892
- lookbehind: true,
4891
+
4892
+ /**
4893
+ * @callback HookCallback
4894
+ * @param {Object<string, any>} env The environment variables of the hook.
4895
+ * @returns {void}
4896
+ * @global
4897
+ * @public
4898
+ */
4899
+
4900
+
4901
+ /* **********************************************
4902
+ Begin prism-markup.js
4903
+ ********************************************** */
4904
+
4905
+ Prism.languages.markup = {
4906
+ 'comment': {
4907
+ pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
4908
+ greedy: true
4909
+ },
4910
+ 'prolog': {
4911
+ pattern: /<\?[\s\S]+?\?>/,
4912
+ greedy: true
4913
+ },
4914
+ 'doctype': {
4915
+ // https://www.w3.org/TR/xml/#NT-doctypedecl
4916
+ pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
4917
+ greedy: true,
4918
+ inside: {
4919
+ 'internal-subset': {
4920
+ pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
4921
+ lookbehind: true,
4922
+ greedy: true,
4923
+ inside: null // see below
4924
+ },
4925
+ 'string': {
4926
+ pattern: /"[^"]*"|'[^']*'/,
4927
+ greedy: true
4928
+ },
4929
+ 'punctuation': /^<!|>$|[[\]]/,
4930
+ 'doctype-tag': /^DOCTYPE/i,
4931
+ 'name': /[^\s<>'"]+/
4932
+ }
4933
+ },
4934
+ 'cdata': {
4935
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
4936
+ greedy: true
4937
+ },
4938
+ 'tag': {
4939
+ pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
4940
+ greedy: true,
4893
4941
  inside: {
4894
- 'attr-name': /^[^\s=]+/,
4942
+ 'tag': {
4943
+ pattern: /^<\/?[^\s>\/]+/,
4944
+ inside: {
4945
+ 'punctuation': /^<\/?/,
4946
+ 'namespace': /^[^\s>\/:]+:/
4947
+ }
4948
+ },
4949
+ 'special-attr': [],
4895
4950
  'attr-value': {
4896
- pattern: /=[\s\S]+/,
4951
+ pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
4897
4952
  inside: {
4898
- 'value': {
4899
- pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
4900
- lookbehind: true,
4901
- alias: [lang, 'language-' + lang],
4902
- inside: Prism.languages[lang]
4903
- },
4904
4953
  'punctuation': [
4905
4954
  {
4906
4955
  pattern: /^=/,
4907
4956
  alias: 'attr-equals'
4908
4957
  },
4909
- /"|'/
4958
+ {
4959
+ pattern: /^(\s*)["']|["']$/,
4960
+ lookbehind: true
4961
+ }
4910
4962
  ]
4911
4963
  }
4964
+ },
4965
+ 'punctuation': /\/?>/,
4966
+ 'attr-name': {
4967
+ pattern: /[^\s>\/]+/,
4968
+ inside: {
4969
+ 'namespace': /^[^\s>\/:]+:/
4970
+ }
4912
4971
  }
4972
+
4913
4973
  }
4914
- });
4915
- }
4916
- });
4974
+ },
4975
+ 'entity': [
4976
+ {
4977
+ pattern: /&[\da-z]{1,8};/i,
4978
+ alias: 'named-entity'
4979
+ },
4980
+ /&#x?[\da-f]{1,8};/i
4981
+ ]
4982
+ };
4917
4983
 
4918
- Prism.languages.html = Prism.languages.markup;
4919
- Prism.languages.mathml = Prism.languages.markup;
4920
- Prism.languages.svg = Prism.languages.markup;
4984
+ Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
4985
+ Prism.languages.markup['entity'];
4986
+ Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
4921
4987
 
4922
- Prism.languages.xml = Prism.languages.extend('markup', {});
4923
- Prism.languages.ssml = Prism.languages.xml;
4924
- Prism.languages.atom = Prism.languages.xml;
4925
- Prism.languages.rss = Prism.languages.xml;
4988
+ // Plugin to make entity title show the real entity, idea by Roman Komarov
4989
+ Prism.hooks.add('wrap', function (env) {
4926
4990
 
4991
+ if (env.type === 'entity') {
4992
+ env.attributes['title'] = env.content.replace(/&amp;/, '&');
4993
+ }
4994
+ });
4927
4995
 
4928
- /* **********************************************
4929
- Begin prism-css.js
4930
- ********************************************** */
4996
+ Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
4997
+ /**
4998
+ * Adds an inlined language to markup.
4999
+ *
5000
+ * An example of an inlined language is CSS with `<style>` tags.
5001
+ *
5002
+ * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
5003
+ * case insensitive.
5004
+ * @param {string} lang The language key.
5005
+ * @example
5006
+ * addInlined('style', 'css');
5007
+ */
5008
+ value: function addInlined(tagName, lang) {
5009
+ var includedCdataInside = {};
5010
+ includedCdataInside['language-' + lang] = {
5011
+ pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
5012
+ lookbehind: true,
5013
+ inside: Prism.languages[lang]
5014
+ };
5015
+ includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
4931
5016
 
4932
- (function (Prism) {
5017
+ var inside = {
5018
+ 'included-cdata': {
5019
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
5020
+ inside: includedCdataInside
5021
+ }
5022
+ };
5023
+ inside['language-' + lang] = {
5024
+ pattern: /[\s\S]+/,
5025
+ inside: Prism.languages[lang]
5026
+ };
4933
5027
 
4934
- var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
5028
+ var def = {};
5029
+ def[tagName] = {
5030
+ pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
5031
+ lookbehind: true,
5032
+ greedy: true,
5033
+ inside: inside
5034
+ };
4935
5035
 
4936
- Prism.languages.css = {
4937
- 'comment': /\/\*[\s\S]*?\*\//,
4938
- 'atrule': {
4939
- pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source),
4940
- inside: {
4941
- 'rule': /^@[\w-]+/,
4942
- 'selector-function-argument': {
4943
- pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
4944
- lookbehind: true,
4945
- alias: 'selector'
4946
- },
4947
- 'keyword': {
4948
- pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
4949
- lookbehind: true
5036
+ Prism.languages.insertBefore('markup', 'cdata', def);
5037
+ }
5038
+ });
5039
+ Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
5040
+ /**
5041
+ * Adds an pattern to highlight languages embedded in HTML attributes.
5042
+ *
5043
+ * An example of an inlined language is CSS with `style` attributes.
5044
+ *
5045
+ * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
5046
+ * case insensitive.
5047
+ * @param {string} lang The language key.
5048
+ * @example
5049
+ * addAttribute('style', 'css');
5050
+ */
5051
+ value: function (attrName, lang) {
5052
+ Prism.languages.markup.tag.inside['special-attr'].push({
5053
+ pattern: RegExp(
5054
+ /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
5055
+ 'i'
5056
+ ),
5057
+ lookbehind: true,
5058
+ inside: {
5059
+ 'attr-name': /^[^\s=]+/,
5060
+ 'attr-value': {
5061
+ pattern: /=[\s\S]+/,
5062
+ inside: {
5063
+ 'value': {
5064
+ pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
5065
+ lookbehind: true,
5066
+ alias: [lang, 'language-' + lang],
5067
+ inside: Prism.languages[lang]
5068
+ },
5069
+ 'punctuation': [
5070
+ {
5071
+ pattern: /^=/,
5072
+ alias: 'attr-equals'
5073
+ },
5074
+ /"|'/
5075
+ ]
5076
+ }
5077
+ }
4950
5078
  }
4951
- // See rest below
4952
- }
4953
- },
4954
- 'url': {
4955
- // https://drafts.csswg.org/css-values-3/#urls
4956
- pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
4957
- greedy: true,
4958
- inside: {
4959
- 'function': /^url/i,
4960
- 'punctuation': /^\(|\)$/,
4961
- 'string': {
4962
- pattern: RegExp('^' + string.source + '$'),
4963
- alias: 'url'
5079
+ });
5080
+ }
5081
+ });
5082
+
5083
+ Prism.languages.html = Prism.languages.markup;
5084
+ Prism.languages.mathml = Prism.languages.markup;
5085
+ Prism.languages.svg = Prism.languages.markup;
5086
+
5087
+ Prism.languages.xml = Prism.languages.extend('markup', {});
5088
+ Prism.languages.ssml = Prism.languages.xml;
5089
+ Prism.languages.atom = Prism.languages.xml;
5090
+ Prism.languages.rss = Prism.languages.xml;
5091
+
5092
+
5093
+ /* **********************************************
5094
+ Begin prism-css.js
5095
+ ********************************************** */
5096
+
5097
+ (function (Prism) {
5098
+
5099
+ var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
5100
+
5101
+ Prism.languages.css = {
5102
+ 'comment': /\/\*[\s\S]*?\*\//,
5103
+ 'atrule': {
5104
+ pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source),
5105
+ inside: {
5106
+ 'rule': /^@[\w-]+/,
5107
+ 'selector-function-argument': {
5108
+ pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
5109
+ lookbehind: true,
5110
+ alias: 'selector'
5111
+ },
5112
+ 'keyword': {
5113
+ pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
5114
+ lookbehind: true
5115
+ }
5116
+ // See rest below
4964
5117
  }
4965
- }
4966
- },
4967
- 'selector': {
4968
- pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
4969
- lookbehind: true
4970
- },
4971
- 'string': {
4972
- pattern: string,
4973
- greedy: true
4974
- },
4975
- 'property': {
4976
- pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
4977
- lookbehind: true
4978
- },
4979
- 'important': /!important\b/i,
4980
- 'function': {
4981
- pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
4982
- lookbehind: true
4983
- },
4984
- 'punctuation': /[(){};:,]/
4985
- };
5118
+ },
5119
+ 'url': {
5120
+ // https://drafts.csswg.org/css-values-3/#urls
5121
+ pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
5122
+ greedy: true,
5123
+ inside: {
5124
+ 'function': /^url/i,
5125
+ 'punctuation': /^\(|\)$/,
5126
+ 'string': {
5127
+ pattern: RegExp('^' + string.source + '$'),
5128
+ alias: 'url'
5129
+ }
5130
+ }
5131
+ },
5132
+ 'selector': {
5133
+ pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
5134
+ lookbehind: true
5135
+ },
5136
+ 'string': {
5137
+ pattern: string,
5138
+ greedy: true
5139
+ },
5140
+ 'property': {
5141
+ pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
5142
+ lookbehind: true
5143
+ },
5144
+ 'important': /!important\b/i,
5145
+ 'function': {
5146
+ pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
5147
+ lookbehind: true
5148
+ },
5149
+ 'punctuation': /[(){};:,]/
5150
+ };
4986
5151
 
4987
- Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
5152
+ Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
4988
5153
 
4989
- var markup = Prism.languages.markup;
4990
- if (markup) {
4991
- markup.tag.addInlined('style', 'css');
4992
- markup.tag.addAttribute('style', 'css');
4993
- }
5154
+ var markup = Prism.languages.markup;
5155
+ if (markup) {
5156
+ markup.tag.addInlined('style', 'css');
5157
+ markup.tag.addAttribute('style', 'css');
5158
+ }
4994
5159
 
4995
- }(Prism));
5160
+ }(Prism));
4996
5161
 
4997
5162
 
4998
- /* **********************************************
4999
- Begin prism-clike.js
5000
- ********************************************** */
5163
+ /* **********************************************
5164
+ Begin prism-clike.js
5165
+ ********************************************** */
5001
5166
 
5002
- Prism.languages.clike = {
5003
- 'comment': [
5004
- {
5005
- pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
5006
- lookbehind: true,
5167
+ Prism.languages.clike = {
5168
+ 'comment': [
5169
+ {
5170
+ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
5171
+ lookbehind: true,
5172
+ greedy: true
5173
+ },
5174
+ {
5175
+ pattern: /(^|[^\\:])\/\/.*/,
5176
+ lookbehind: true,
5177
+ greedy: true
5178
+ }
5179
+ ],
5180
+ 'string': {
5181
+ pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
5007
5182
  greedy: true
5008
5183
  },
5009
- {
5010
- pattern: /(^|[^\\:])\/\/.*/,
5184
+ 'class-name': {
5185
+ pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
5011
5186
  lookbehind: true,
5012
- greedy: true
5013
- }
5014
- ],
5015
- 'string': {
5016
- pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
5017
- greedy: true
5018
- },
5019
- 'class-name': {
5020
- pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
5021
- lookbehind: true,
5022
- inside: {
5023
- 'punctuation': /[.\\]/
5024
- }
5025
- },
5026
- 'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
5027
- 'boolean': /\b(?:false|true)\b/,
5028
- 'function': /\b\w+(?=\()/,
5029
- 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
5030
- 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
5031
- 'punctuation': /[{}[\];(),.:]/
5032
- };
5187
+ inside: {
5188
+ 'punctuation': /[.\\]/
5189
+ }
5190
+ },
5191
+ 'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
5192
+ 'boolean': /\b(?:false|true)\b/,
5193
+ 'function': /\b\w+(?=\()/,
5194
+ 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
5195
+ 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
5196
+ 'punctuation': /[{}[\];(),.:]/
5197
+ };
5033
5198
 
5034
5199
 
5035
- /* **********************************************
5036
- Begin prism-javascript.js
5037
- ********************************************** */
5200
+ /* **********************************************
5201
+ Begin prism-javascript.js
5202
+ ********************************************** */
5038
5203
 
5039
- Prism.languages.javascript = Prism.languages.extend('clike', {
5040
- 'class-name': [
5041
- Prism.languages.clike['class-name'],
5042
- {
5043
- pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
5044
- lookbehind: true
5045
- }
5046
- ],
5047
- 'keyword': [
5048
- {
5049
- pattern: /((?:^|\})\s*)catch\b/,
5050
- lookbehind: true
5051
- },
5052
- {
5053
- 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/,
5204
+ Prism.languages.javascript = Prism.languages.extend('clike', {
5205
+ 'class-name': [
5206
+ Prism.languages.clike['class-name'],
5207
+ {
5208
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
5209
+ lookbehind: true
5210
+ }
5211
+ ],
5212
+ 'keyword': [
5213
+ {
5214
+ pattern: /((?:^|\})\s*)catch\b/,
5215
+ lookbehind: true
5216
+ },
5217
+ {
5218
+ 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/,
5219
+ lookbehind: true
5220
+ },
5221
+ ],
5222
+ // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
5223
+ 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
5224
+ 'number': {
5225
+ pattern: RegExp(
5226
+ /(^|[^\w$])/.source +
5227
+ '(?:' +
5228
+ (
5229
+ // constant
5230
+ /NaN|Infinity/.source +
5231
+ '|' +
5232
+ // binary integer
5233
+ /0[bB][01]+(?:_[01]+)*n?/.source +
5234
+ '|' +
5235
+ // octal integer
5236
+ /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
5237
+ '|' +
5238
+ // hexadecimal integer
5239
+ /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
5240
+ '|' +
5241
+ // decimal bigint
5242
+ /\d+(?:_\d+)*n/.source +
5243
+ '|' +
5244
+ // decimal number (integer or float) but no bigint
5245
+ /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
5246
+ ) +
5247
+ ')' +
5248
+ /(?![\w$])/.source
5249
+ ),
5054
5250
  lookbehind: true
5055
5251
  },
5056
- ],
5057
- // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
5058
- 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
5059
- 'number': {
5060
- pattern: RegExp(
5061
- /(^|[^\w$])/.source +
5062
- '(?:' +
5063
- (
5064
- // constant
5065
- /NaN|Infinity/.source +
5066
- '|' +
5067
- // binary integer
5068
- /0[bB][01]+(?:_[01]+)*n?/.source +
5069
- '|' +
5070
- // octal integer
5071
- /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
5072
- '|' +
5073
- // hexadecimal integer
5074
- /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
5075
- '|' +
5076
- // decimal bigint
5077
- /\d+(?:_\d+)*n/.source +
5252
+ 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
5253
+ });
5254
+
5255
+ Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
5256
+
5257
+ Prism.languages.insertBefore('javascript', 'keyword', {
5258
+ 'regex': {
5259
+ pattern: RegExp(
5260
+ // lookbehind
5261
+ // eslint-disable-next-line regexp/no-dupe-characters-character-class
5262
+ /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
5263
+ // Regex pattern:
5264
+ // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
5265
+ // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
5266
+ // with the only syntax, so we have to define 2 different regex patterns.
5267
+ /\//.source +
5268
+ '(?:' +
5269
+ /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
5078
5270
  '|' +
5079
- // decimal number (integer or float) but no bigint
5080
- /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
5081
- ) +
5082
- ')' +
5083
- /(?![\w$])/.source
5084
- ),
5085
- lookbehind: true
5086
- },
5087
- 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
5088
- });
5089
-
5090
- Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
5091
-
5092
- Prism.languages.insertBefore('javascript', 'keyword', {
5093
- 'regex': {
5094
- pattern: RegExp(
5095
- // lookbehind
5096
- // eslint-disable-next-line regexp/no-dupe-characters-character-class
5097
- /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
5098
- // Regex pattern:
5099
- // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
5100
- // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
5101
- // with the only syntax, so we have to define 2 different regex patterns.
5102
- /\//.source +
5103
- '(?:' +
5104
- /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
5105
- '|' +
5106
- // `v` flag syntax. This supports 3 levels of nested character classes.
5107
- /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
5108
- ')' +
5109
- // lookahead
5110
- /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
5111
- ),
5112
- lookbehind: true,
5113
- greedy: true,
5114
- inside: {
5115
- 'regex-source': {
5116
- pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
5117
- lookbehind: true,
5118
- alias: 'language-regex',
5119
- inside: Prism.languages.regex
5120
- },
5121
- 'regex-delimiter': /^\/|\/$/,
5122
- 'regex-flags': /^[a-z]+$/,
5123
- }
5124
- },
5125
- // This must be declared before keyword because we use "function" inside the look-forward
5126
- 'function-variable': {
5127
- 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*=>))/,
5128
- alias: 'function'
5129
- },
5130
- 'parameter': [
5131
- {
5132
- pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
5133
- lookbehind: true,
5134
- inside: Prism.languages.javascript
5135
- },
5136
- {
5137
- pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
5271
+ // `v` flag syntax. This supports 3 levels of nested character classes.
5272
+ /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
5273
+ ')' +
5274
+ // lookahead
5275
+ /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
5276
+ ),
5138
5277
  lookbehind: true,
5139
- inside: Prism.languages.javascript
5278
+ greedy: true,
5279
+ inside: {
5280
+ 'regex-source': {
5281
+ pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
5282
+ lookbehind: true,
5283
+ alias: 'language-regex',
5284
+ inside: Prism.languages.regex
5285
+ },
5286
+ 'regex-delimiter': /^\/|\/$/,
5287
+ 'regex-flags': /^[a-z]+$/,
5288
+ }
5140
5289
  },
5141
- {
5142
- pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
5143
- lookbehind: true,
5144
- inside: Prism.languages.javascript
5290
+ // This must be declared before keyword because we use "function" inside the look-forward
5291
+ 'function-variable': {
5292
+ 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*=>))/,
5293
+ alias: 'function'
5145
5294
  },
5146
- {
5147
- 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*\{)/,
5148
- lookbehind: true,
5149
- inside: Prism.languages.javascript
5150
- }
5151
- ],
5152
- 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
5153
- });
5154
-
5155
- Prism.languages.insertBefore('javascript', 'string', {
5156
- 'hashbang': {
5157
- pattern: /^#!.*/,
5158
- greedy: true,
5159
- alias: 'comment'
5160
- },
5161
- 'template-string': {
5162
- pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
5163
- greedy: true,
5164
- inside: {
5165
- 'template-punctuation': {
5166
- pattern: /^`|`$/,
5167
- alias: 'string'
5295
+ 'parameter': [
5296
+ {
5297
+ pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
5298
+ lookbehind: true,
5299
+ inside: Prism.languages.javascript
5168
5300
  },
5169
- 'interpolation': {
5170
- pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
5301
+ {
5302
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
5171
5303
  lookbehind: true,
5172
- inside: {
5173
- 'interpolation-punctuation': {
5174
- pattern: /^\$\{|\}$/,
5175
- alias: 'punctuation'
5176
- },
5177
- rest: Prism.languages.javascript
5178
- }
5304
+ inside: Prism.languages.javascript
5179
5305
  },
5180
- 'string': /[\s\S]+/
5306
+ {
5307
+ pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
5308
+ lookbehind: true,
5309
+ inside: Prism.languages.javascript
5310
+ },
5311
+ {
5312
+ 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*\{)/,
5313
+ lookbehind: true,
5314
+ inside: Prism.languages.javascript
5315
+ }
5316
+ ],
5317
+ 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
5318
+ });
5319
+
5320
+ Prism.languages.insertBefore('javascript', 'string', {
5321
+ 'hashbang': {
5322
+ pattern: /^#!.*/,
5323
+ greedy: true,
5324
+ alias: 'comment'
5325
+ },
5326
+ 'template-string': {
5327
+ pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
5328
+ greedy: true,
5329
+ inside: {
5330
+ 'template-punctuation': {
5331
+ pattern: /^`|`$/,
5332
+ alias: 'string'
5333
+ },
5334
+ 'interpolation': {
5335
+ pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
5336
+ lookbehind: true,
5337
+ inside: {
5338
+ 'interpolation-punctuation': {
5339
+ pattern: /^\$\{|\}$/,
5340
+ alias: 'punctuation'
5341
+ },
5342
+ rest: Prism.languages.javascript
5343
+ }
5344
+ },
5345
+ 'string': /[\s\S]+/
5346
+ }
5347
+ },
5348
+ 'string-property': {
5349
+ pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
5350
+ lookbehind: true,
5351
+ greedy: true,
5352
+ alias: 'property'
5181
5353
  }
5182
- },
5183
- 'string-property': {
5184
- pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
5185
- lookbehind: true,
5186
- greedy: true,
5187
- alias: 'property'
5188
- }
5189
- });
5354
+ });
5190
5355
 
5191
- Prism.languages.insertBefore('javascript', 'operator', {
5192
- 'literal-property': {
5193
- pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
5194
- lookbehind: true,
5195
- alias: 'property'
5196
- },
5197
- });
5356
+ Prism.languages.insertBefore('javascript', 'operator', {
5357
+ 'literal-property': {
5358
+ pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
5359
+ lookbehind: true,
5360
+ alias: 'property'
5361
+ },
5362
+ });
5198
5363
 
5199
- if (Prism.languages.markup) {
5200
- Prism.languages.markup.tag.addInlined('script', 'javascript');
5364
+ if (Prism.languages.markup) {
5365
+ Prism.languages.markup.tag.addInlined('script', 'javascript');
5201
5366
 
5202
- // add attribute support for all DOM events.
5203
- // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
5204
- Prism.languages.markup.tag.addAttribute(
5205
- /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,
5206
- 'javascript'
5207
- );
5208
- }
5367
+ // add attribute support for all DOM events.
5368
+ // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
5369
+ Prism.languages.markup.tag.addAttribute(
5370
+ /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,
5371
+ 'javascript'
5372
+ );
5373
+ }
5209
5374
 
5210
- Prism.languages.js = Prism.languages.javascript;
5375
+ Prism.languages.js = Prism.languages.javascript;
5211
5376
 
5212
5377
 
5213
- /* **********************************************
5214
- Begin prism-file-highlight.js
5215
- ********************************************** */
5378
+ /* **********************************************
5379
+ Begin prism-file-highlight.js
5380
+ ********************************************** */
5216
5381
 
5217
- (function () {
5382
+ (function () {
5218
5383
 
5219
- if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5220
- return;
5221
- }
5384
+ if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5385
+ return;
5386
+ }
5222
5387
 
5223
- // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
5224
- if (!Element.prototype.matches) {
5225
- Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
5226
- }
5388
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
5389
+ if (!Element.prototype.matches) {
5390
+ Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
5391
+ }
5227
5392
 
5228
- var LOADING_MESSAGE = 'Loading…';
5229
- var FAILURE_MESSAGE = function (status, message) {
5230
- return '✖ Error ' + status + ' while fetching file: ' + message;
5231
- };
5232
- var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty';
5233
-
5234
- var EXTENSIONS = {
5235
- 'js': 'javascript',
5236
- 'py': 'python',
5237
- 'rb': 'ruby',
5238
- 'ps1': 'powershell',
5239
- 'psm1': 'powershell',
5240
- 'sh': 'bash',
5241
- 'bat': 'batch',
5242
- 'h': 'c',
5243
- 'tex': 'latex'
5244
- };
5393
+ var LOADING_MESSAGE = 'Loading…';
5394
+ var FAILURE_MESSAGE = function (status, message) {
5395
+ return '✖ Error ' + status + ' while fetching file: ' + message;
5396
+ };
5397
+ var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty';
5398
+
5399
+ var EXTENSIONS = {
5400
+ 'js': 'javascript',
5401
+ 'py': 'python',
5402
+ 'rb': 'ruby',
5403
+ 'ps1': 'powershell',
5404
+ 'psm1': 'powershell',
5405
+ 'sh': 'bash',
5406
+ 'bat': 'batch',
5407
+ 'h': 'c',
5408
+ 'tex': 'latex'
5409
+ };
5245
5410
 
5246
- var STATUS_ATTR = 'data-src-status';
5247
- var STATUS_LOADING = 'loading';
5248
- var STATUS_LOADED = 'loaded';
5249
- var STATUS_FAILED = 'failed';
5411
+ var STATUS_ATTR = 'data-src-status';
5412
+ var STATUS_LOADING = 'loading';
5413
+ var STATUS_LOADED = 'loaded';
5414
+ var STATUS_FAILED = 'failed';
5250
5415
 
5251
- var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
5252
- + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])';
5416
+ var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
5417
+ + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])';
5253
5418
 
5254
- /**
5255
- * Loads the given file.
5256
- *
5257
- * @param {string} src The URL or path of the source file to load.
5258
- * @param {(result: string) => void} success
5259
- * @param {(reason: string) => void} error
5260
- */
5261
- function loadFile(src, success, error) {
5262
- var xhr = new XMLHttpRequest();
5263
- xhr.open('GET', src, true);
5264
- xhr.onreadystatechange = function () {
5265
- if (xhr.readyState == 4) {
5266
- if (xhr.status < 400 && xhr.responseText) {
5267
- success(xhr.responseText);
5268
- } else {
5269
- if (xhr.status >= 400) {
5270
- error(FAILURE_MESSAGE(xhr.status, xhr.statusText));
5419
+ /**
5420
+ * Loads the given file.
5421
+ *
5422
+ * @param {string} src The URL or path of the source file to load.
5423
+ * @param {(result: string) => void} success
5424
+ * @param {(reason: string) => void} error
5425
+ */
5426
+ function loadFile(src, success, error) {
5427
+ var xhr = new XMLHttpRequest();
5428
+ xhr.open('GET', src, true);
5429
+ xhr.onreadystatechange = function () {
5430
+ if (xhr.readyState == 4) {
5431
+ if (xhr.status < 400 && xhr.responseText) {
5432
+ success(xhr.responseText);
5271
5433
  } else {
5272
- error(FAILURE_EMPTY_MESSAGE);
5434
+ if (xhr.status >= 400) {
5435
+ error(FAILURE_MESSAGE(xhr.status, xhr.statusText));
5436
+ } else {
5437
+ error(FAILURE_EMPTY_MESSAGE);
5438
+ }
5273
5439
  }
5274
5440
  }
5275
- }
5276
- };
5277
- xhr.send(null);
5278
- }
5441
+ };
5442
+ xhr.send(null);
5443
+ }
5279
5444
 
5280
- /**
5281
- * Parses the given range.
5282
- *
5283
- * This returns a range with inclusive ends.
5284
- *
5285
- * @param {string | null | undefined} range
5286
- * @returns {[number, number | undefined] | undefined}
5287
- */
5288
- function parseRange(range) {
5289
- var m = /^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(range || '');
5290
- if (m) {
5291
- var start = Number(m[1]);
5292
- var comma = m[2];
5293
- var end = m[3];
5294
-
5295
- if (!comma) {
5296
- return [start, start];
5297
- }
5298
- if (!end) {
5299
- return [start, undefined];
5445
+ /**
5446
+ * Parses the given range.
5447
+ *
5448
+ * This returns a range with inclusive ends.
5449
+ *
5450
+ * @param {string | null | undefined} range
5451
+ * @returns {[number, number | undefined] | undefined}
5452
+ */
5453
+ function parseRange(range) {
5454
+ var m = /^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(range || '');
5455
+ if (m) {
5456
+ var start = Number(m[1]);
5457
+ var comma = m[2];
5458
+ var end = m[3];
5459
+
5460
+ if (!comma) {
5461
+ return [start, start];
5462
+ }
5463
+ if (!end) {
5464
+ return [start, undefined];
5465
+ }
5466
+ return [start, Number(end)];
5300
5467
  }
5301
- return [start, Number(end)];
5468
+ return undefined;
5302
5469
  }
5303
- return undefined;
5304
- }
5305
5470
 
5306
- Prism.hooks.add('before-highlightall', function (env) {
5307
- env.selector += ', ' + SELECTOR;
5308
- });
5471
+ Prism.hooks.add('before-highlightall', function (env) {
5472
+ env.selector += ', ' + SELECTOR;
5473
+ });
5309
5474
 
5310
- Prism.hooks.add('before-sanity-check', function (env) {
5311
- var pre = /** @type {HTMLPreElement} */ (env.element);
5312
- if (pre.matches(SELECTOR)) {
5313
- env.code = ''; // fast-path the whole thing and go to complete
5475
+ Prism.hooks.add('before-sanity-check', function (env) {
5476
+ var pre = /** @type {HTMLPreElement} */ (env.element);
5477
+ if (pre.matches(SELECTOR)) {
5478
+ env.code = ''; // fast-path the whole thing and go to complete
5314
5479
 
5315
- pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading
5480
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading
5316
5481
 
5317
- // add code element with loading message
5318
- var code = pre.appendChild(document.createElement('CODE'));
5319
- code.textContent = LOADING_MESSAGE;
5482
+ // add code element with loading message
5483
+ var code = pre.appendChild(document.createElement('CODE'));
5484
+ code.textContent = LOADING_MESSAGE;
5320
5485
 
5321
- var src = pre.getAttribute('data-src');
5486
+ var src = pre.getAttribute('data-src');
5322
5487
 
5323
- var language = env.language;
5324
- if (language === 'none') {
5325
- // the language might be 'none' because there is no language set;
5326
- // in this case, we want to use the extension as the language
5327
- var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1];
5328
- language = EXTENSIONS[extension] || extension;
5329
- }
5488
+ var language = env.language;
5489
+ if (language === 'none') {
5490
+ // the language might be 'none' because there is no language set;
5491
+ // in this case, we want to use the extension as the language
5492
+ var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1];
5493
+ language = EXTENSIONS[extension] || extension;
5494
+ }
5330
5495
 
5331
- // set language classes
5332
- Prism.util.setLanguage(code, language);
5333
- Prism.util.setLanguage(pre, language);
5496
+ // set language classes
5497
+ Prism.util.setLanguage(code, language);
5498
+ Prism.util.setLanguage(pre, language);
5334
5499
 
5335
- // preload the language
5336
- var autoloader = Prism.plugins.autoloader;
5337
- if (autoloader) {
5338
- autoloader.loadLanguages(language);
5339
- }
5500
+ // preload the language
5501
+ var autoloader = Prism.plugins.autoloader;
5502
+ if (autoloader) {
5503
+ autoloader.loadLanguages(language);
5504
+ }
5340
5505
 
5341
- // load file
5342
- loadFile(
5343
- src,
5344
- function (text) {
5345
- // mark as loaded
5346
- pre.setAttribute(STATUS_ATTR, STATUS_LOADED);
5506
+ // load file
5507
+ loadFile(
5508
+ src,
5509
+ function (text) {
5510
+ // mark as loaded
5511
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADED);
5347
5512
 
5348
- // handle data-range
5349
- var range = parseRange(pre.getAttribute('data-range'));
5350
- if (range) {
5351
- var lines = text.split(/\r\n?|\n/g);
5513
+ // handle data-range
5514
+ var range = parseRange(pre.getAttribute('data-range'));
5515
+ if (range) {
5516
+ var lines = text.split(/\r\n?|\n/g);
5352
5517
 
5353
- // the range is one-based and inclusive on both ends
5354
- var start = range[0];
5355
- var end = range[1] == null ? lines.length : range[1];
5518
+ // the range is one-based and inclusive on both ends
5519
+ var start = range[0];
5520
+ var end = range[1] == null ? lines.length : range[1];
5356
5521
 
5357
- if (start < 0) { start += lines.length; }
5358
- start = Math.max(0, Math.min(start - 1, lines.length));
5359
- if (end < 0) { end += lines.length; }
5360
- end = Math.max(0, Math.min(end, lines.length));
5522
+ if (start < 0) { start += lines.length; }
5523
+ start = Math.max(0, Math.min(start - 1, lines.length));
5524
+ if (end < 0) { end += lines.length; }
5525
+ end = Math.max(0, Math.min(end, lines.length));
5361
5526
 
5362
- text = lines.slice(start, end).join('\n');
5527
+ text = lines.slice(start, end).join('\n');
5363
5528
 
5364
- // add data-start for line numbers
5365
- if (!pre.hasAttribute('data-start')) {
5366
- pre.setAttribute('data-start', String(start + 1));
5529
+ // add data-start for line numbers
5530
+ if (!pre.hasAttribute('data-start')) {
5531
+ pre.setAttribute('data-start', String(start + 1));
5532
+ }
5367
5533
  }
5368
- }
5369
5534
 
5370
- // highlight code
5371
- code.textContent = text;
5372
- Prism.highlightElement(code);
5373
- },
5374
- function (error) {
5375
- // mark as failed
5376
- pre.setAttribute(STATUS_ATTR, STATUS_FAILED);
5535
+ // highlight code
5536
+ code.textContent = text;
5537
+ Prism.highlightElement(code);
5538
+ },
5539
+ function (error) {
5540
+ // mark as failed
5541
+ pre.setAttribute(STATUS_ATTR, STATUS_FAILED);
5377
5542
 
5378
- code.textContent = error;
5379
- }
5380
- );
5381
- }
5382
- });
5543
+ code.textContent = error;
5544
+ }
5545
+ );
5546
+ }
5547
+ });
5383
5548
 
5384
- Prism.plugins.fileHighlight = {
5385
- /**
5386
- * Executes the File Highlight plugin for all matching `pre` elements under the given container.
5387
- *
5388
- * Note: Elements which are already loaded or currently loading will not be touched by this method.
5389
- *
5390
- * @param {ParentNode} [container=document]
5391
- */
5392
- highlight: function highlight(container) {
5393
- var elements = (container || document).querySelectorAll(SELECTOR);
5549
+ Prism.plugins.fileHighlight = {
5550
+ /**
5551
+ * Executes the File Highlight plugin for all matching `pre` elements under the given container.
5552
+ *
5553
+ * Note: Elements which are already loaded or currently loading will not be touched by this method.
5554
+ *
5555
+ * @param {ParentNode} [container=document]
5556
+ */
5557
+ highlight: function highlight(container) {
5558
+ var elements = (container || document).querySelectorAll(SELECTOR);
5394
5559
 
5395
- for (var i = 0, element; (element = elements[i++]);) {
5396
- Prism.highlightElement(element);
5560
+ for (var i = 0, element; (element = elements[i++]);) {
5561
+ Prism.highlightElement(element);
5562
+ }
5397
5563
  }
5398
- }
5399
- };
5400
-
5401
- var logged = false;
5402
- /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */
5403
- Prism.fileHighlight = function () {
5404
- if (!logged) {
5405
- console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.');
5406
- logged = true;
5407
- }
5408
- Prism.plugins.fileHighlight.highlight.apply(this, arguments);
5409
- };
5564
+ };
5410
5565
 
5411
- }());
5412
- } (prism));
5413
-
5414
- Prism.languages.python = {
5415
- 'comment': {
5416
- pattern: /(^|[^\\])#.*/,
5417
- lookbehind: true,
5418
- greedy: true
5419
- },
5420
- 'string-interpolation': {
5421
- pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
5422
- greedy: true,
5423
- inside: {
5424
- 'interpolation': {
5425
- // "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}"
5426
- pattern: /((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,
5427
- lookbehind: true,
5428
- inside: {
5429
- 'format-spec': {
5430
- pattern: /(:)[^:(){}]+(?=\}$)/,
5431
- lookbehind: true
5432
- },
5433
- 'conversion-option': {
5434
- pattern: /![sra](?=[:}]$)/,
5435
- alias: 'punctuation'
5436
- },
5437
- rest: null
5566
+ var logged = false;
5567
+ /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */
5568
+ Prism.fileHighlight = function () {
5569
+ if (!logged) {
5570
+ console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.');
5571
+ logged = true;
5438
5572
  }
5439
- },
5440
- 'string': /[\s\S]+/
5441
- }
5442
- },
5443
- 'triple-quoted-string': {
5444
- pattern: /(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,
5445
- greedy: true,
5446
- alias: 'string'
5447
- },
5448
- 'string': {
5449
- pattern: /(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
5450
- greedy: true
5451
- },
5452
- 'function': {
5453
- pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,
5454
- lookbehind: true
5455
- },
5456
- 'class-name': {
5457
- pattern: /(\bclass\s+)\w+/i,
5458
- lookbehind: true
5459
- },
5460
- 'decorator': {
5461
- pattern: /(^[\t ]*)@\w+(?:\.\w+)*/m,
5462
- lookbehind: true,
5463
- alias: ['annotation', 'punctuation'],
5464
- inside: {
5465
- 'punctuation': /\./
5466
- }
5467
- },
5468
- 'keyword': /\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
5469
- 'builtin': /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
5470
- 'boolean': /\b(?:False|None|True)\b/,
5471
- 'number': /\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,
5472
- 'operator': /[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
5473
- 'punctuation': /[{}[\];(),.:]/
5474
- };
5573
+ Prism.plugins.fileHighlight.highlight.apply(this, arguments);
5574
+ };
5475
5575
 
5476
- Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python;
5576
+ }());
5577
+ } (prism));
5578
+ return prism.exports;
5579
+ }
5477
5580
 
5478
- Prism.languages.py = Prism.languages.python;
5581
+ requirePrism();
5479
5582
 
5480
- (function () {
5583
+ var prismPython = {};
5481
5584
 
5482
- if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5483
- return;
5484
- }
5585
+ var hasRequiredPrismPython;
5485
5586
 
5486
- /**
5487
- * Plugin name which is used as a class name for <pre> which is activating the plugin
5488
- *
5489
- * @type {string}
5490
- */
5491
- var PLUGIN_NAME = 'line-numbers';
5587
+ function requirePrismPython () {
5588
+ if (hasRequiredPrismPython) return prismPython;
5589
+ hasRequiredPrismPython = 1;
5590
+ Prism.languages.python = {
5591
+ 'comment': {
5592
+ pattern: /(^|[^\\])#.*/,
5593
+ lookbehind: true,
5594
+ greedy: true
5595
+ },
5596
+ 'string-interpolation': {
5597
+ pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
5598
+ greedy: true,
5599
+ inside: {
5600
+ 'interpolation': {
5601
+ // "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}"
5602
+ pattern: /((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,
5603
+ lookbehind: true,
5604
+ inside: {
5605
+ 'format-spec': {
5606
+ pattern: /(:)[^:(){}]+(?=\}$)/,
5607
+ lookbehind: true
5608
+ },
5609
+ 'conversion-option': {
5610
+ pattern: /![sra](?=[:}]$)/,
5611
+ alias: 'punctuation'
5612
+ },
5613
+ rest: null
5614
+ }
5615
+ },
5616
+ 'string': /[\s\S]+/
5617
+ }
5618
+ },
5619
+ 'triple-quoted-string': {
5620
+ pattern: /(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,
5621
+ greedy: true,
5622
+ alias: 'string'
5623
+ },
5624
+ 'string': {
5625
+ pattern: /(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
5626
+ greedy: true
5627
+ },
5628
+ 'function': {
5629
+ pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,
5630
+ lookbehind: true
5631
+ },
5632
+ 'class-name': {
5633
+ pattern: /(\bclass\s+)\w+/i,
5634
+ lookbehind: true
5635
+ },
5636
+ 'decorator': {
5637
+ pattern: /(^[\t ]*)@\w+(?:\.\w+)*/m,
5638
+ lookbehind: true,
5639
+ alias: ['annotation', 'punctuation'],
5640
+ inside: {
5641
+ 'punctuation': /\./
5642
+ }
5643
+ },
5644
+ 'keyword': /\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
5645
+ 'builtin': /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
5646
+ 'boolean': /\b(?:False|None|True)\b/,
5647
+ 'number': /\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,
5648
+ 'operator': /[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
5649
+ 'punctuation': /[{}[\];(),.:]/
5650
+ };
5492
5651
 
5493
- /**
5494
- * Regular expression used for determining line breaks
5495
- *
5496
- * @type {RegExp}
5497
- */
5498
- var NEW_LINE_EXP = /\n(?!$)/g;
5652
+ Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python;
5499
5653
 
5654
+ Prism.languages.py = Prism.languages.python;
5655
+ return prismPython;
5656
+ }
5500
5657
 
5501
- /**
5502
- * Global exports
5503
- */
5504
- var config = Prism.plugins.lineNumbers = {
5505
- /**
5506
- * Get node for provided line number
5507
- *
5508
- * @param {Element} element pre element
5509
- * @param {number} number line number
5510
- * @returns {Element|undefined}
5511
- */
5512
- getLine: function (element, number) {
5513
- if (element.tagName !== 'PRE' || !element.classList.contains(PLUGIN_NAME)) {
5514
- return;
5515
- }
5658
+ requirePrismPython();
5516
5659
 
5517
- var lineNumberRows = element.querySelector('.line-numbers-rows');
5518
- if (!lineNumberRows) {
5519
- return;
5520
- }
5521
- var lineNumberStart = parseInt(element.getAttribute('data-start'), 10) || 1;
5522
- var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1);
5660
+ var prismLineNumbers = {};
5523
5661
 
5524
- if (number < lineNumberStart) {
5525
- number = lineNumberStart;
5526
- }
5527
- if (number > lineNumberEnd) {
5528
- number = lineNumberEnd;
5529
- }
5662
+ var hasRequiredPrismLineNumbers;
5530
5663
 
5531
- var lineIndex = number - lineNumberStart;
5664
+ function requirePrismLineNumbers () {
5665
+ if (hasRequiredPrismLineNumbers) return prismLineNumbers;
5666
+ hasRequiredPrismLineNumbers = 1;
5667
+ (function () {
5532
5668
 
5533
- return lineNumberRows.children[lineIndex];
5534
- },
5669
+ if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5670
+ return;
5671
+ }
5535
5672
 
5536
5673
  /**
5537
- * Resizes the line numbers of the given element.
5674
+ * Plugin name which is used as a class name for <pre> which is activating the plugin
5538
5675
  *
5539
- * This function will not add line numbers. It will only resize existing ones.
5540
- *
5541
- * @param {HTMLElement} element A `<pre>` element with line numbers.
5542
- * @returns {void}
5676
+ * @type {string}
5543
5677
  */
5544
- resize: function (element) {
5545
- resizeElements([element]);
5546
- },
5678
+ var PLUGIN_NAME = 'line-numbers';
5547
5679
 
5548
5680
  /**
5549
- * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
5550
- * the current viewport.
5551
- *
5552
- * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
5681
+ * Regular expression used for determining line breaks
5553
5682
  *
5554
- * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
5555
- *
5556
- * @type {boolean}
5683
+ * @type {RegExp}
5557
5684
  */
5558
- assumeViewportIndependence: true
5559
- };
5685
+ var NEW_LINE_EXP = /\n(?!$)/g;
5560
5686
 
5561
- /**
5562
- * Resizes the given elements.
5563
- *
5564
- * @param {HTMLElement[]} elements
5565
- */
5566
- function resizeElements(elements) {
5567
- elements = elements.filter(function (e) {
5568
- var codeStyles = getStyles(e);
5569
- var whiteSpace = codeStyles['white-space'];
5570
- return whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line';
5571
- });
5572
5687
 
5573
- if (elements.length == 0) {
5574
- return;
5575
- }
5688
+ /**
5689
+ * Global exports
5690
+ */
5691
+ var config = Prism.plugins.lineNumbers = {
5692
+ /**
5693
+ * Get node for provided line number
5694
+ *
5695
+ * @param {Element} element pre element
5696
+ * @param {number} number line number
5697
+ * @returns {Element|undefined}
5698
+ */
5699
+ getLine: function (element, number) {
5700
+ if (element.tagName !== 'PRE' || !element.classList.contains(PLUGIN_NAME)) {
5701
+ return;
5702
+ }
5576
5703
 
5577
- var infos = elements.map(function (element) {
5578
- var codeElement = element.querySelector('code');
5579
- var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
5580
- if (!codeElement || !lineNumbersWrapper) {
5581
- return undefined;
5582
- }
5704
+ var lineNumberRows = element.querySelector('.line-numbers-rows');
5705
+ if (!lineNumberRows) {
5706
+ return;
5707
+ }
5708
+ var lineNumberStart = parseInt(element.getAttribute('data-start'), 10) || 1;
5709
+ var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1);
5710
+
5711
+ if (number < lineNumberStart) {
5712
+ number = lineNumberStart;
5713
+ }
5714
+ if (number > lineNumberEnd) {
5715
+ number = lineNumberEnd;
5716
+ }
5583
5717
 
5584
- /** @type {HTMLElement} */
5585
- var lineNumberSizer = element.querySelector('.line-numbers-sizer');
5586
- var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
5718
+ var lineIndex = number - lineNumberStart;
5719
+
5720
+ return lineNumberRows.children[lineIndex];
5721
+ },
5722
+
5723
+ /**
5724
+ * Resizes the line numbers of the given element.
5725
+ *
5726
+ * This function will not add line numbers. It will only resize existing ones.
5727
+ *
5728
+ * @param {HTMLElement} element A `<pre>` element with line numbers.
5729
+ * @returns {void}
5730
+ */
5731
+ resize: function (element) {
5732
+ resizeElements([element]);
5733
+ },
5734
+
5735
+ /**
5736
+ * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
5737
+ * the current viewport.
5738
+ *
5739
+ * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
5740
+ *
5741
+ * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
5742
+ *
5743
+ * @type {boolean}
5744
+ */
5745
+ assumeViewportIndependence: true
5746
+ };
5587
5747
 
5588
- if (!lineNumberSizer) {
5589
- lineNumberSizer = document.createElement('span');
5590
- lineNumberSizer.className = 'line-numbers-sizer';
5748
+ /**
5749
+ * Resizes the given elements.
5750
+ *
5751
+ * @param {HTMLElement[]} elements
5752
+ */
5753
+ function resizeElements(elements) {
5754
+ elements = elements.filter(function (e) {
5755
+ var codeStyles = getStyles(e);
5756
+ var whiteSpace = codeStyles['white-space'];
5757
+ return whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line';
5758
+ });
5591
5759
 
5592
- codeElement.appendChild(lineNumberSizer);
5760
+ if (elements.length == 0) {
5761
+ return;
5593
5762
  }
5594
5763
 
5595
- lineNumberSizer.innerHTML = '0';
5596
- lineNumberSizer.style.display = 'block';
5764
+ var infos = elements.map(function (element) {
5765
+ var codeElement = element.querySelector('code');
5766
+ var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
5767
+ if (!codeElement || !lineNumbersWrapper) {
5768
+ return undefined;
5769
+ }
5597
5770
 
5598
- var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
5599
- lineNumberSizer.innerHTML = '';
5771
+ /** @type {HTMLElement} */
5772
+ var lineNumberSizer = element.querySelector('.line-numbers-sizer');
5773
+ var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
5600
5774
 
5601
- return {
5602
- element: element,
5603
- lines: codeLines,
5604
- lineHeights: [],
5605
- oneLinerHeight: oneLinerHeight,
5606
- sizer: lineNumberSizer,
5607
- };
5608
- }).filter(Boolean);
5609
-
5610
- infos.forEach(function (info) {
5611
- var lineNumberSizer = info.sizer;
5612
- var lines = info.lines;
5613
- var lineHeights = info.lineHeights;
5614
- var oneLinerHeight = info.oneLinerHeight;
5615
-
5616
- lineHeights[lines.length - 1] = undefined;
5617
- lines.forEach(function (line, index) {
5618
- if (line && line.length > 1) {
5619
- var e = lineNumberSizer.appendChild(document.createElement('span'));
5620
- e.style.display = 'block';
5621
- e.textContent = line;
5622
- } else {
5623
- lineHeights[index] = oneLinerHeight;
5775
+ if (!lineNumberSizer) {
5776
+ lineNumberSizer = document.createElement('span');
5777
+ lineNumberSizer.className = 'line-numbers-sizer';
5778
+
5779
+ codeElement.appendChild(lineNumberSizer);
5624
5780
  }
5781
+
5782
+ lineNumberSizer.innerHTML = '0';
5783
+ lineNumberSizer.style.display = 'block';
5784
+
5785
+ var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
5786
+ lineNumberSizer.innerHTML = '';
5787
+
5788
+ return {
5789
+ element: element,
5790
+ lines: codeLines,
5791
+ lineHeights: [],
5792
+ oneLinerHeight: oneLinerHeight,
5793
+ sizer: lineNumberSizer,
5794
+ };
5795
+ }).filter(Boolean);
5796
+
5797
+ infos.forEach(function (info) {
5798
+ var lineNumberSizer = info.sizer;
5799
+ var lines = info.lines;
5800
+ var lineHeights = info.lineHeights;
5801
+ var oneLinerHeight = info.oneLinerHeight;
5802
+
5803
+ lineHeights[lines.length - 1] = undefined;
5804
+ lines.forEach(function (line, index) {
5805
+ if (line && line.length > 1) {
5806
+ var e = lineNumberSizer.appendChild(document.createElement('span'));
5807
+ e.style.display = 'block';
5808
+ e.textContent = line;
5809
+ } else {
5810
+ lineHeights[index] = oneLinerHeight;
5811
+ }
5812
+ });
5625
5813
  });
5626
- });
5627
5814
 
5628
- infos.forEach(function (info) {
5629
- var lineNumberSizer = info.sizer;
5630
- var lineHeights = info.lineHeights;
5815
+ infos.forEach(function (info) {
5816
+ var lineNumberSizer = info.sizer;
5817
+ var lineHeights = info.lineHeights;
5631
5818
 
5632
- var childIndex = 0;
5633
- for (var i = 0; i < lineHeights.length; i++) {
5634
- if (lineHeights[i] === undefined) {
5635
- lineHeights[i] = lineNumberSizer.children[childIndex++].getBoundingClientRect().height;
5819
+ var childIndex = 0;
5820
+ for (var i = 0; i < lineHeights.length; i++) {
5821
+ if (lineHeights[i] === undefined) {
5822
+ lineHeights[i] = lineNumberSizer.children[childIndex++].getBoundingClientRect().height;
5823
+ }
5636
5824
  }
5637
- }
5638
- });
5825
+ });
5639
5826
 
5640
- infos.forEach(function (info) {
5641
- var lineNumberSizer = info.sizer;
5642
- var wrapper = info.element.querySelector('.line-numbers-rows');
5827
+ infos.forEach(function (info) {
5828
+ var lineNumberSizer = info.sizer;
5829
+ var wrapper = info.element.querySelector('.line-numbers-rows');
5643
5830
 
5644
- lineNumberSizer.style.display = 'none';
5645
- lineNumberSizer.innerHTML = '';
5831
+ lineNumberSizer.style.display = 'none';
5832
+ lineNumberSizer.innerHTML = '';
5646
5833
 
5647
- info.lineHeights.forEach(function (height, lineNumber) {
5648
- wrapper.children[lineNumber].style.height = height + 'px';
5834
+ info.lineHeights.forEach(function (height, lineNumber) {
5835
+ wrapper.children[lineNumber].style.height = height + 'px';
5836
+ });
5649
5837
  });
5650
- });
5651
- }
5652
-
5653
- /**
5654
- * Returns style declarations for the element
5655
- *
5656
- * @param {Element} element
5657
- */
5658
- function getStyles(element) {
5659
- if (!element) {
5660
- return null;
5661
5838
  }
5662
5839
 
5663
- return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
5664
- }
5840
+ /**
5841
+ * Returns style declarations for the element
5842
+ *
5843
+ * @param {Element} element
5844
+ */
5845
+ function getStyles(element) {
5846
+ if (!element) {
5847
+ return null;
5848
+ }
5665
5849
 
5666
- var lastWidth = undefined;
5667
- window.addEventListener('resize', function () {
5668
- if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
5669
- return;
5850
+ return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
5670
5851
  }
5671
- lastWidth = window.innerWidth;
5672
5852
 
5673
- resizeElements(Array.prototype.slice.call(document.querySelectorAll('pre.' + PLUGIN_NAME)));
5674
- });
5853
+ var lastWidth = undefined;
5854
+ window.addEventListener('resize', function () {
5855
+ if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
5856
+ return;
5857
+ }
5858
+ lastWidth = window.innerWidth;
5675
5859
 
5676
- Prism.hooks.add('complete', function (env) {
5677
- if (!env.code) {
5678
- return;
5679
- }
5860
+ resizeElements(Array.prototype.slice.call(document.querySelectorAll('pre.' + PLUGIN_NAME)));
5861
+ });
5680
5862
 
5681
- var code = /** @type {Element} */ (env.element);
5682
- var pre = /** @type {HTMLElement} */ (code.parentNode);
5863
+ Prism.hooks.add('complete', function (env) {
5864
+ if (!env.code) {
5865
+ return;
5866
+ }
5683
5867
 
5684
- // works only for <code> wrapped inside <pre> (not inline)
5685
- if (!pre || !/pre/i.test(pre.nodeName)) {
5686
- return;
5687
- }
5868
+ var code = /** @type {Element} */ (env.element);
5869
+ var pre = /** @type {HTMLElement} */ (code.parentNode);
5688
5870
 
5689
- // Abort if line numbers already exists
5690
- if (code.querySelector('.line-numbers-rows')) {
5691
- return;
5692
- }
5871
+ // works only for <code> wrapped inside <pre> (not inline)
5872
+ if (!pre || !/pre/i.test(pre.nodeName)) {
5873
+ return;
5874
+ }
5693
5875
 
5694
- // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
5695
- if (!Prism.util.isActive(code, PLUGIN_NAME)) {
5696
- return;
5697
- }
5876
+ // Abort if line numbers already exists
5877
+ if (code.querySelector('.line-numbers-rows')) {
5878
+ return;
5879
+ }
5698
5880
 
5699
- // Remove the class 'line-numbers' from the <code>
5700
- code.classList.remove(PLUGIN_NAME);
5701
- // Add the class 'line-numbers' to the <pre>
5702
- pre.classList.add(PLUGIN_NAME);
5881
+ // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
5882
+ if (!Prism.util.isActive(code, PLUGIN_NAME)) {
5883
+ return;
5884
+ }
5703
5885
 
5704
- var match = env.code.match(NEW_LINE_EXP);
5705
- var linesNum = match ? match.length + 1 : 1;
5706
- var lineNumbersWrapper;
5886
+ // Remove the class 'line-numbers' from the <code>
5887
+ code.classList.remove(PLUGIN_NAME);
5888
+ // Add the class 'line-numbers' to the <pre>
5889
+ pre.classList.add(PLUGIN_NAME);
5707
5890
 
5708
- var lines = new Array(linesNum + 1).join('<span></span>');
5891
+ var match = env.code.match(NEW_LINE_EXP);
5892
+ var linesNum = match ? match.length + 1 : 1;
5893
+ var lineNumbersWrapper;
5709
5894
 
5710
- lineNumbersWrapper = document.createElement('span');
5711
- lineNumbersWrapper.setAttribute('aria-hidden', 'true');
5712
- lineNumbersWrapper.className = 'line-numbers-rows';
5713
- lineNumbersWrapper.innerHTML = lines;
5895
+ var lines = new Array(linesNum + 1).join('<span></span>');
5714
5896
 
5715
- if (pre.hasAttribute('data-start')) {
5716
- pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
5717
- }
5897
+ lineNumbersWrapper = document.createElement('span');
5898
+ lineNumbersWrapper.setAttribute('aria-hidden', 'true');
5899
+ lineNumbersWrapper.className = 'line-numbers-rows';
5900
+ lineNumbersWrapper.innerHTML = lines;
5901
+
5902
+ if (pre.hasAttribute('data-start')) {
5903
+ pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
5904
+ }
5905
+
5906
+ env.element.appendChild(lineNumbersWrapper);
5718
5907
 
5719
- env.element.appendChild(lineNumbersWrapper);
5908
+ resizeElements([pre]);
5720
5909
 
5721
- resizeElements([pre]);
5910
+ Prism.hooks.run('line-numbers', env);
5911
+ });
5722
5912
 
5723
- Prism.hooks.run('line-numbers', env);
5724
- });
5913
+ Prism.hooks.add('line-numbers', function (env) {
5914
+ env.plugins = env.plugins || {};
5915
+ env.plugins.lineNumbers = true;
5916
+ });
5725
5917
 
5726
- Prism.hooks.add('line-numbers', function (env) {
5727
- env.plugins = env.plugins || {};
5728
- env.plugins.lineNumbers = true;
5729
- });
5918
+ }());
5919
+ return prismLineNumbers;
5920
+ }
5730
5921
 
5731
- }());
5922
+ requirePrismLineNumbers();
5732
5923
 
5733
5924
  const initialize = () => {
5734
5925
  // @ts-ignore
@@ -5748,7 +5939,11 @@ const initialize = () => {
5748
5939
  }
5749
5940
  };
5750
5941
  // @ts-ignore
5751
- window.setResults = (playerNames, places, parameters, verbose) => {
5942
+ window.setResults = (playerNames, seed, places, statistics, parameters, verbose) => {
5943
+ // @ts-ignore
5944
+ parameters = parameters.toJs();
5945
+ // @ts-ignore
5946
+ statistics = statistics.toJs();
5752
5947
  const results = getLocalStorage("Results");
5753
5948
  if (!results[playerNames.join(", ")]) {
5754
5949
  results[playerNames.join(", ")] = {};
@@ -5756,7 +5951,11 @@ const initialize = () => {
5756
5951
  if (!results[playerNames.join(", ")][JSON.stringify(parameters)]) {
5757
5952
  results[playerNames.join(", ")][JSON.stringify(parameters)] = [];
5758
5953
  }
5759
- results[playerNames.join(", ")][JSON.stringify(parameters)].push(places);
5954
+ results[playerNames.join(", ")][JSON.stringify(parameters)].push({
5955
+ seed,
5956
+ places,
5957
+ statistics,
5958
+ });
5760
5959
  setLocalStorage("Results", results);
5761
5960
  updatePointModifier();
5762
5961
  // @ts-ignore