diff --git a/app/components/markdown/markdown_code_block/index.tsx b/app/components/markdown/markdown_code_block/index.tsx
index 44b0ae36c..63e17b8ce 100644
--- a/app/components/markdown/markdown_code_block/index.tsx
+++ b/app/components/markdown/markdown_code_block/index.tsx
@@ -9,9 +9,11 @@ import {Keyboard, StyleSheet, Text, TextStyle, TouchableOpacity, View} from 'rea
import FormattedText from '@components/formatted_text';
import SlideUpPanelItem, {ITEM_HEIGHT} from '@components/slide_up_panel_item';
+import SyntaxHighlighter from '@components/syntax_highlight';
+import {Screens} from '@constants';
import {useTheme} from '@context/theme';
import {bottomSheet, dismissBottomSheet, goToScreen} from '@screens/navigation';
-import {getDisplayNameForLanguage} from '@utils/markdown';
+import {getHighlightLanguageFromNameOrAlias, getHighlightLanguageName} from '@utils/markdown';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@@ -34,36 +36,10 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
borderWidth: StyleSheet.hairlineWidth,
flexDirection: 'row',
},
- lineNumbers: {
- alignItems: 'center',
- backgroundColor: changeOpacity(theme.centerChannelColor, 0.05),
- borderRightColor: changeOpacity(theme.centerChannelColor, 0.15),
- borderRightWidth: StyleSheet.hairlineWidth,
- flexDirection: 'column',
- justifyContent: 'flex-start',
- paddingVertical: 4,
- width: 21,
- },
- lineNumbersText: {
- color: changeOpacity(theme.centerChannelColor, 0.5),
- fontSize: 12,
- lineHeight: 18,
- },
- rightColumn: {
- flexDirection: 'column',
- flex: 1,
- paddingHorizontal: 6,
- paddingVertical: 4,
- },
code: {
flexDirection: 'row',
overflow: 'scroll', // Doesn't actually cause a scrollbar, but stops text from wrapping
},
- codeText: {
- color: changeOpacity(theme.centerChannelColor, 0.65),
- fontSize: 12,
- lineHeight: 18,
- },
plusMoreLinesText: {
color: changeOpacity(theme.centerChannelColor, 0.4),
fontSize: 11,
@@ -93,12 +69,14 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc
const style = getStyleSheet(theme);
const handlePress = preventDoubleTap(() => {
- const screen = 'Code';
+ const screen = Screens.CODE;
const passProps = {
- content,
+ code: content,
+ language,
+ textStyle,
};
- const languageDisplayName = getDisplayNameForLanguage(language);
+ const languageDisplayName = getHighlightLanguageName(language);
let title: string;
if (languageDisplayName) {
title = intl.formatMessage(
@@ -182,7 +160,7 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc
const renderLanguageBlock = () => {
if (language) {
- const languageDisplayName = getDisplayNameForLanguage(language);
+ const languageDisplayName = getHighlightLanguageName(language);
if (languageDisplayName) {
return (
@@ -199,15 +177,6 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc
const {content: codeContent, numberOfLines} = trimContent(content);
- const getLineNumbers = () => {
- let lineNumbers = '1';
- for (let i = 1; i < Math.min(numberOfLines, MAX_LINES); i++) {
- const line = (i + 1).toString();
- lineNumbers += '\n' + line;
- }
- return lineNumbers;
- };
-
const renderPlusMoreLines = () => {
if (numberOfLines > MAX_LINES) {
return (
@@ -225,26 +194,28 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc
};
return (
-
-
-
- {getLineNumbers()}
-
-
-
-
- {codeContent}
-
+ <>
+
+
+
+
+
+
+ {renderPlusMoreLines()}
- {renderPlusMoreLines()}
+ {renderLanguageBlock()}
- {renderLanguageBlock()}
-
-
+
+ >
);
};
export default MarkdownCodeBlock;
+
diff --git a/app/components/syntax_highlight/index.tsx b/app/components/syntax_highlight/index.tsx
new file mode 100644
index 000000000..8a2d56393
--- /dev/null
+++ b/app/components/syntax_highlight/index.tsx
@@ -0,0 +1,85 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback, useMemo} from 'react';
+import {StyleSheet, TextStyle, View} from 'react-native';
+import SyntaxHighlighter from 'react-syntax-highlighter';
+import {github, monokai, solarizedDark, solarizedLight} from 'react-syntax-highlighter/dist/cjs/styles/hljs';
+
+import {useTheme} from '@context/theme';
+
+import CodeHighlightRenderer from './renderer';
+
+type Props = {
+ code: string;
+ language: string;
+ textStyle: TextStyle;
+ selectable?: boolean;
+}
+
+const codeTheme: Record = {
+ github,
+ monokai,
+ 'solarized-dark': solarizedDark,
+ 'solarized-light': solarizedLight,
+};
+
+const styles = StyleSheet.create({
+ preTag: {
+ padding: 5,
+ width: '100%',
+ },
+ flex: {
+ flex: 1,
+ },
+});
+
+const Highlighter = ({code, language, textStyle, selectable = false}: Props) => {
+ const theme = useTheme();
+ const style = codeTheme[theme.codeTheme] || github;
+ const preTagStyle = useMemo(() => [
+ styles.preTag,
+ selectable && styles.flex,
+ {backgroundColor: style.hljs.background || theme.centerChannelBg},
+ ],
+ [theme, selectable, style]);
+
+ const nativeRenderer = useCallback(({rows, stylesheet}) => {
+ const digits = rows.length.toString().length;
+ return (
+
+ );
+ }, [textStyle, theme, style]);
+
+ const preTag = useCallback((info) => (
+
+ {info.children}
+
+ ), [preTagStyle]);
+
+ return (
+
+ {code}
+
+ );
+};
+
+export default Highlighter;
diff --git a/app/components/syntax_highlight/renderer.tsx b/app/components/syntax_highlight/renderer.tsx
new file mode 100644
index 000000000..d08be58a9
--- /dev/null
+++ b/app/components/syntax_highlight/renderer.tsx
@@ -0,0 +1,144 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback} from 'react';
+import {FlatList, ScrollView, StyleSheet, Text} from 'react-native';
+import {createStyleObject} from 'react-syntax-highlighter/create-element';
+
+import {changeOpacity} from '@utils/theme';
+
+type CreateChildren = {
+ digits: number;
+ stylesheet: any;
+ fontFamily: string;
+ fontSize?: number;
+ selectable?: boolean;
+}
+
+type CreateNativeElement = CreateChildren & {
+ node: any;
+ key: string;
+ defaultColor: string;
+}
+
+type Props = CreateChildren & Pick & {
+ rows: any[];
+}
+
+const styles = StyleSheet.create({
+ wrapped: {
+ flexWrap: 'nowrap',
+ },
+});
+
+function createChildren({stylesheet, fontSize = 12, fontFamily, selectable, digits}: CreateChildren) {
+ let childrenCount = 0;
+ return (children: any[], defaultColor: string) => {
+ childrenCount += 1;
+ return children.map((child, i) => {
+ return createNativeElement({
+ node: child,
+ stylesheet,
+ key: `code-segment-${childrenCount}-${i}`,
+ defaultColor,
+ fontSize,
+ fontFamily,
+ selectable,
+ digits,
+ });
+ });
+ };
+}
+
+function createNativeElement({node, stylesheet, key, defaultColor, fontFamily, fontSize = 12, selectable, digits}: CreateNativeElement) {
+ const {properties, type, tagName: TagName, value} = node;
+ const startingStyle = {fontFamily, fontSize, height: fontSize + 7};
+ if (properties?.key?.startsWith('line-number')) {
+ let valueString = `${node.children[0].value}. `;
+ for (let i = valueString.length; i < digits + 2; i++) {
+ valueString += ' ';
+ }
+
+ return (
+
+ {valueString}
+
+ );
+ }
+ if (type === 'text') {
+ return (
+
+ {value}
+
+ );
+ } else if (TagName) {
+ const childrenCreator = createChildren({stylesheet, fontSize, fontFamily, digits});
+ if (properties.style?.display) {
+ properties.style.display = 'flex';
+ }
+ if (properties.style?.paddingRight) {
+ delete properties.style.paddingRight;
+ }
+ if (properties.style?.userSelect) {
+ delete properties.style.userSelect;
+ }
+ const style = createStyleObject(
+ properties.className,
+ {
+ color: defaultColor,
+ ...properties.style,
+ ...startingStyle,
+ },
+ stylesheet,
+ );
+ const children = childrenCreator(node.children, style.color || defaultColor);
+ return (
+
+ {children}
+
+ );
+ }
+
+ return null;
+}
+
+const CodeHighlightRenderer = ({defaultColor, digits, fontFamily, fontSize, rows, selectable, stylesheet}: Props) => {
+ const renderItem = useCallback(({item, index}) => {
+ return createNativeElement({
+ node: item,
+ stylesheet,
+ key: `code-segment-${index}`,
+ defaultColor,
+ fontFamily,
+ fontSize,
+ selectable,
+ digits,
+ });
+ }, [defaultColor, digits, fontFamily, fontSize, stylesheet]);
+
+ return (
+
+
+
+ );
+};
+
+export default CodeHighlightRenderer;
diff --git a/app/constants/screens.ts b/app/constants/screens.ts
index d949bfe55..196448a86 100644
--- a/app/constants/screens.ts
+++ b/app/constants/screens.ts
@@ -11,6 +11,7 @@ export const CHANNEL = 'Channel';
export const CHANNEL_ADD_PEOPLE = 'ChannelAddPeople';
export const CHANNEL_DETAILS = 'ChannelDetails';
export const CHANNEL_EDIT = 'ChannelEdit';
+export const CODE = 'Code';
export const CREATE_DIRECT_MESSAGE = 'CreateDirectMessage';
export const CREATE_OR_EDIT_CHANNEL = 'CreateOrEditChannel';
export const CUSTOM_STATUS = 'CustomStatus';
@@ -51,6 +52,7 @@ export default {
CHANNEL_ADD_PEOPLE,
CHANNEL_EDIT,
CHANNEL_DETAILS,
+ CODE,
CREATE_DIRECT_MESSAGE,
CUSTOM_STATUS_CLEAR_AFTER,
CUSTOM_STATUS,
diff --git a/app/screens/code/index.tsx b/app/screens/code/index.tsx
new file mode 100644
index 000000000..991360a6e
--- /dev/null
+++ b/app/screens/code/index.tsx
@@ -0,0 +1,41 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import {useManagedConfig} from '@mattermost/react-native-emm';
+import React from 'react';
+import {StyleSheet, TextStyle} from 'react-native';
+import {SafeAreaView, Edge} from 'react-native-safe-area-context';
+
+import SyntaxHiglight from '@components/syntax_highlight';
+
+type Props = {
+ code: string;
+ language: string;
+ textStyle: TextStyle;
+}
+
+const edges: Edge[] = ['left', 'right'];
+
+const styles = StyleSheet.create({
+ flex: {flex: 1},
+});
+
+const Code = ({code, language, textStyle}: Props) => {
+ const managedConfig = useManagedConfig();
+
+ return (
+
+
+
+ );
+};
+
+export default Code;
diff --git a/app/screens/index.tsx b/app/screens/index.tsx
index ff64a4130..232556e6d 100644
--- a/app/screens/index.tsx
+++ b/app/screens/index.tsx
@@ -70,6 +70,9 @@ Navigation.setLazyComponentRegistrator((screenName) => {
case Screens.CHANNEL:
screen = withServerDatabase(require('@screens/channel').default);
break;
+ case Screens.CODE:
+ screen = withServerDatabase(require('@screens/code').default);
+ break;
case Screens.CREATE_OR_EDIT_CHANNEL:
screen = withServerDatabase(require('@screens/create_or_edit_channel').default);
break;
diff --git a/app/utils/markdown/index.ts b/app/utils/markdown/index.ts
index a57e35502..ca4295fbc 100644
--- a/app/utils/markdown/index.ts
+++ b/app/utils/markdown/index.ts
@@ -7,6 +7,14 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {getViewPortWidth} from '../images';
+type LanguageObject = {
+ [key: string]: {
+ name: string;
+ extensions: string[];
+ aliases?: Set;
+ };
+}
+
export function getCodeFont() {
return Platform.OS === 'ios' ? 'Menlo' : 'monospace';
}
@@ -119,71 +127,88 @@ export const getMarkdownBlockStyles = makeStyleSheetFromTheme((theme: Theme) =>
};
});
-const languages: Record = {
- actionscript: 'ActionScript',
- applescript: 'AppleScript',
- bash: 'Bash',
- clojure: 'Clojure',
- coffeescript: 'CoffeeScript',
- cpp: 'C++',
- cs: 'C#',
- css: 'CSS',
- d: 'D',
- dart: 'Dart',
- delphi: 'Delphi',
- diff: 'Diff',
- django: 'Django',
- dockerfile: 'Dockerfile',
- elixir: 'Elixir',
- erlang: 'Erlang',
- fortran: 'Fortran',
- fsharp: 'F#',
- gcode: 'G-code',
- go: 'Go',
- groovy: 'Groovy',
- handlebars: 'Handlebars',
- haskell: 'Haskell',
- haxe: 'Haxe',
- html: 'HTML',
- java: 'Java',
- javascript: 'JavaScript',
- js: 'JavaScript',
- json: 'JSON',
- julia: 'Julia',
- kotlin: 'Kotlin',
- latex: 'LaTeX',
- less: 'Less',
- lisp: 'Lisp',
- lua: 'Lua',
- makefile: 'Makefile',
- markdown: 'Markdown',
- matlab: 'Matlab',
- objectivec: 'Objective-C',
- ocaml: 'OCaml',
- perl: 'Perl',
- php: 'PHP',
- powershell: 'PowerShell',
- puppet: 'Puppet',
- python: 'Python',
- r: 'R',
- ruby: 'Ruby',
- rust: 'Rust',
- scala: 'Scala',
- scheme: 'Scheme',
- scss: 'SCSS',
- smalltalk: 'Smalltalk',
- sql: 'SQL',
- swift: 'Swift',
- tex: 'TeX',
- vbnet: 'VB.NET',
- vbscript: 'VBScript',
- verilog: 'Verilog',
- xml: 'XML',
- yaml: 'YAML',
+const highlightedLanguages: LanguageObject = {
+ actionscript: {name: 'ActionScript', extensions: ['as'], aliases: new Set(['as', 'as3'])},
+ applescript: {name: 'AppleScript', extensions: ['applescript', 'osascript', 'scpt']},
+ bash: {name: 'Bash', extensions: ['sh'], aliases: new Set('sh')},
+ clojure: {name: 'Clojure', extensions: ['clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic']},
+ coffeescript: {name: 'CoffeeScript', extensions: ['coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced'], aliases: new Set(['coffee', 'coffee-script'])},
+ cpp: {name: 'C/C++', extensions: ['cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp'], aliases: new Set(['c++', 'c'])},
+ cs: {name: 'C#', extensions: ['cs', 'csharp'], aliases: new Set(['c#', 'csharp'])},
+ css: {name: 'CSS', extensions: ['css']},
+ d: {name: 'D', extensions: ['d', 'di'], aliases: new Set('dlang')},
+ dart: {name: 'Dart', extensions: ['dart']},
+ delphi: {name: 'Delphi', extensions: ['delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm']},
+ diff: {name: 'Diff', extensions: ['diff', 'patch'], aliases: new Set(['patch', 'udiff'])},
+ django: {name: 'Django', extensions: ['django', 'jinja']},
+ dockerfile: {name: 'Dockerfile', extensions: ['dockerfile', 'docker'], aliases: new Set('docker')},
+ elixir: {name: 'Elixir', extensions: ['ex', 'exs'], aliases: new Set(['ex', 'exs'])},
+ erlang: {name: 'Erlang', extensions: ['erl'], aliases: new Set('erl')},
+ fortran: {name: 'Fortran', extensions: ['f90', 'f95']},
+ fsharp: {name: 'F#', extensions: ['fsharp', 'fs']},
+ gcode: {name: 'G-Code', extensions: ['gcode', 'nc']},
+ go: {name: 'Go', extensions: ['go'], aliases: new Set('golang')},
+ groovy: {name: 'Groovy', extensions: ['groovy']},
+ handlebars: {name: 'Handlebars', extensions: ['handlebars', 'hbs', 'html.hbs', 'html.handlebars'], aliases: new Set(['hbs', 'mustache'])},
+ haskell: {name: 'Haskell', extensions: ['hs'], aliases: new Set('hs')},
+ haxe: {name: 'Haxe', extensions: ['hx']},
+ java: {name: 'Java', extensions: ['java', 'jsp']},
+ javascript: {name: 'JavaScript', extensions: ['js', 'jsx'], aliases: new Set(['js', 'jsx'])},
+ json: {name: 'JSON', extensions: ['json']},
+ julia: {name: 'Julia', extensions: ['jl'], aliases: new Set('jl')},
+ kotlin: {name: 'Kotlin', extensions: ['kt', 'ktm', 'kts']},
+ latex: {name: 'LaTeX', extensions: ['tex'], aliases: new Set('tex')},
+ less: {name: 'Less', extensions: ['less']},
+ lisp: {name: 'Lisp', extensions: ['lisp']},
+ lua: {name: 'Lua', extensions: ['lua']},
+ makefile: {name: 'Makefile', extensions: ['mk', 'mak'], aliases: new Set(['make', 'mf', 'gnumake', 'bsdmake'])},
+ markdown: {name: 'Markdown', extensions: ['md', 'mkdown', 'mkd'], aliases: new Set(['md', 'mkd'])},
+ matlab: {name: 'Matlab', extensions: ['matlab', 'm'], aliases: new Set('m')},
+ objectivec: {name: 'Objective C', extensions: ['mm', 'objc', 'obj-c'], aliases: new Set(['objective_c', 'objc'])},
+ ocaml: {name: 'OCaml', extensions: ['ml']},
+ perl: {name: 'Perl', extensions: ['perl', 'pl'], aliases: new Set('pl')},
+ pgsql: {name: 'PostgreSQL', extensions: ['pgsql', 'postgres', 'postgresql'], aliases: new Set(['postgres', 'postgresql'])},
+ php: {name: 'PHP', extensions: ['php', 'php3', 'php4', 'php5', 'php6'], aliases: new Set(['php3', 'php4', 'php5'])},
+ powershell: {name: 'PowerShell', extensions: ['ps', 'ps1'], aliases: new Set('posh')},
+ puppet: {name: 'Puppet', extensions: ['pp'], aliases: new Set('pp')},
+ python: {name: 'Python', extensions: ['py', 'gyp'], aliases: new Set('py')},
+ r: {name: 'R', extensions: ['r'], aliases: new Set(['r', 's'])},
+ ruby: {name: 'Ruby', extensions: ['ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb'], aliases: new Set('rb')},
+ rust: {name: 'Rust', extensions: ['rs'], aliases: new Set('rs')},
+ scala: {name: 'Scala', extensions: ['scala']},
+ scheme: {name: 'Scheme', extensions: ['scm', 'sld']},
+ scss: {name: 'SCSS', extensions: ['scss']},
+ smalltalk: {name: 'Smalltalk', extensions: ['st'], aliases: new Set(['st', 'squeak'])},
+ sql: {name: 'SQL', extensions: ['sql']},
+ stylus: {name: 'Stylus', extensions: ['styl'], aliases: new Set('styl')},
+ swift: {name: 'Swift', extensions: ['swift']},
+ text: {name: 'Text', extensions: ['txt', 'log']},
+ typescript: {name: 'TypeScript', extensions: ['ts', 'tsx'], aliases: new Set(['ts', 'tsx'])},
+ vbnet: {name: 'VB.Net', extensions: ['vbnet', 'vb', 'bas'], aliases: new Set(['vb', 'visualbasic'])},
+ vbscript: {name: 'VBScript', extensions: ['vbs']},
+ verilog: {name: 'Verilog', extensions: ['v', 'veo', 'sv', 'svh']},
+ vhdl: {name: 'VHDL', extensions: ['vhd', 'vhdl']},
+ xml: {name: 'HTML, XML', extensions: ['xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist']},
+ yaml: {name: 'YAML', extensions: ['yaml'], aliases: new Set('yml')},
};
-export function getDisplayNameForLanguage(language: string) {
- return languages[language.toLowerCase()] || '';
+export function getHighlightLanguageFromNameOrAlias(name: string) {
+ const langName: string = name.toLowerCase();
+ if (highlightedLanguages[langName]) {
+ return langName;
+ }
+
+ return Object.keys(highlightedLanguages).find((key) => {
+ return highlightedLanguages[key].aliases?.has(langName);
+ }) || '';
+}
+
+export function getHighlightLanguageName(language: string): string {
+ const name: string | undefined = getHighlightLanguageFromNameOrAlias(language);
+ if (!name) {
+ return '';
+ }
+ return highlightedLanguages[name].name || '';
}
export function escapeRegex(text: string) {
diff --git a/jest.config.js b/jest.config.js
index 4b034c1e2..a081ff4b8 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -20,6 +20,6 @@ module.exports = {
'/dist/assets/images/video_player/$1@2x.png',
},
transformIgnorePatterns: [
- 'node_modules/(?!(@react-native|react-native)|jail-monkey|@sentry/react-native|react-navigation|@react-native-community/cameraroll|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|sentry-expo|native-base|validator)',
+ 'node_modules/(?!(@react-native|react-native)|jail-monkey|@sentry/react-native|@react-native-community/cameraroll|react-clone-referenced-element|@react-native-community|react-navigation|@react-navigation/.*|validator|react-syntax-highlighter/.*)',
],
};
diff --git a/package-lock.json b/package-lock.json
index 9f8a4dd4b..d531aeef7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -84,6 +84,7 @@
"react-native-video": "5.2.0",
"react-native-webview": "11.18.1",
"react-native-youtube": "2.0.2",
+ "react-syntax-highlighter": "15.5.0",
"reanimated-bottom-sheet": "1.0.0-alpha.22",
"rn-placeholder": "3.0.3",
"semver": "7.3.6",
@@ -119,6 +120,7 @@
"@types/react-native-button": "3.0.1",
"@types/react-native-share": "3.3.3",
"@types/react-native-video": "5.0.13",
+ "@types/react-syntax-highlighter": "13.5.2",
"@types/react-test-renderer": "17.0.1",
"@types/semver": "7.3.9",
"@types/shallow-equals": "1.0.0",
@@ -5631,6 +5633,14 @@
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz",
"integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA=="
},
+ "node_modules/@types/hast": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
+ "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
@@ -5785,6 +5795,15 @@
"@types/react-native": "*"
}
},
+ "node_modules/@types/react-syntax-highlighter": {
+ "version": "13.5.2",
+ "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-13.5.2.tgz",
+ "integrity": "sha512-sRZoKZBGKaE7CzMvTTgz+0x/aVR58ZYUTfB7HN76vC+yQnvo1FWtzNARBt0fGqcLGEVakEzMu/CtPzssmanu8Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/react-test-renderer": {
"version": "17.0.1",
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz",
@@ -5829,6 +5848,11 @@
"integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==",
"dev": true
},
+ "node_modules/@types/unist": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
+ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
+ },
"node_modules/@types/url-parse": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/@types/url-parse/-/url-parse-1.4.8.tgz",
@@ -8079,6 +8103,33 @@
"node": ">=10"
}
},
+ "node_modules/character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/charcodes": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz",
@@ -8430,6 +8481,15 @@
"node": ">= 0.8"
}
},
+ "node_modules/comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/command-exists": {
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
@@ -10921,6 +10981,18 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fault": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+ "dependencies": {
+ "format": "^0.2.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/fb-watchman": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
@@ -11389,6 +11461,14 @@
"node": ">= 6"
}
},
+ "node_modules/format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
"node_modules/fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -11892,6 +11972,31 @@
"minimalistic-assert": "^1.0.1"
}
},
+ "node_modules/hast-util-parse-selector": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
+ "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hastscript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
+ "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^1.0.0",
+ "hast-util-parse-selector": "^2.0.0",
+ "property-information": "^5.0.0",
+ "space-separated-tokens": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -11939,6 +12044,14 @@
"node": ">= 8"
}
},
+ "node_modules/highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -12342,6 +12455,28 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "dependencies": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -12470,6 +12605,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-descriptor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
@@ -12569,6 +12713,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
@@ -15531,6 +15684,19 @@
"react-native": ">=0.46"
}
},
+ "node_modules/lowlight": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
+ "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
+ "dependencies": {
+ "fault": "^1.0.0",
+ "highlight.js": "~10.7.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@@ -17929,6 +18095,23 @@
"safe-buffer": "^5.1.1"
}
},
+ "node_modules/parse-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+ "dependencies": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
@@ -18278,6 +18461,14 @@
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true
},
+ "node_modules/prismjs": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
+ "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -18364,6 +18555,18 @@
"signal-exit": "^3.0.2"
}
},
+ "node_modules/property-information": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -19390,6 +19593,21 @@
"react": "^16.0.0 || ^17.0.0"
}
},
+ "node_modules/react-syntax-highlighter": {
+ "version": "15.5.0",
+ "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
+ "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "highlight.js": "^10.4.1",
+ "lowlight": "^1.17.0",
+ "prismjs": "^1.27.0",
+ "refractor": "^3.6.0"
+ },
+ "peerDependencies": {
+ "react": ">= 0.14.0"
+ }
+ },
"node_modules/react-test-renderer": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz",
@@ -19530,6 +19748,20 @@
"fbjs": "^0.8.9"
}
},
+ "node_modules/refractor": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
+ "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
+ "dependencies": {
+ "hastscript": "^6.0.0",
+ "parse-entities": "^2.0.0",
+ "prismjs": "~1.27.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -20567,6 +20799,15 @@
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
"deprecated": "See https://github.com/lydell/source-map-url#deprecated"
},
+ "node_modules/space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
@@ -27219,6 +27460,14 @@
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz",
"integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA=="
},
+ "@types/hast": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
+ "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
+ "requires": {
+ "@types/unist": "*"
+ }
+ },
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
@@ -27373,6 +27622,15 @@
"@types/react-native": "*"
}
},
+ "@types/react-syntax-highlighter": {
+ "version": "13.5.2",
+ "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-13.5.2.tgz",
+ "integrity": "sha512-sRZoKZBGKaE7CzMvTTgz+0x/aVR58ZYUTfB7HN76vC+yQnvo1FWtzNARBt0fGqcLGEVakEzMu/CtPzssmanu8Q==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/react-test-renderer": {
"version": "17.0.1",
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz",
@@ -27417,6 +27675,11 @@
"integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==",
"dev": true
},
+ "@types/unist": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
+ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
+ },
"@types/url-parse": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/@types/url-parse/-/url-parse-1.4.8.tgz",
@@ -29154,6 +29417,21 @@
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
"dev": true
},
+ "character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw=="
+ },
+ "character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA=="
+ },
+ "character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
+ },
"charcodes": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz",
@@ -29441,6 +29719,11 @@
"delayed-stream": "~1.0.0"
}
},
+ "comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw=="
+ },
"command-exists": {
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
@@ -31392,6 +31675,14 @@
"reusify": "^1.0.4"
}
},
+ "fault": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+ "requires": {
+ "format": "^0.2.0"
+ }
+ },
"fb-watchman": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
@@ -31776,6 +32067,11 @@
"mime-types": "^2.1.12"
}
},
+ "format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs="
+ },
"fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -32151,6 +32447,23 @@
"minimalistic-assert": "^1.0.1"
}
},
+ "hast-util-parse-selector": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
+ "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ=="
+ },
+ "hastscript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
+ "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^1.0.0",
+ "hast-util-parse-selector": "^2.0.0",
+ "property-information": "^5.0.0",
+ "space-separated-tokens": "^1.0.0"
+ }
+ },
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -32191,6 +32504,11 @@
}
}
},
+ "highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -32501,6 +32819,20 @@
"kind-of": "^6.0.0"
}
},
+ "is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg=="
+ },
+ "is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "requires": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ }
+ },
"is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -32592,6 +32924,11 @@
"has-tostringtag": "^1.0.0"
}
},
+ "is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw=="
+ },
"is-descriptor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
@@ -32655,6 +32992,11 @@
"is-extglob": "^2.1.1"
}
},
+ "is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw=="
+ },
"is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
@@ -34882,6 +35224,15 @@
"react-native-safe-modules": "^1.0.3"
}
},
+ "lowlight": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
+ "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
+ "requires": {
+ "fault": "^1.0.0",
+ "highlight.js": "~10.7.0"
+ }
+ },
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@@ -36832,6 +37183,19 @@
"safe-buffer": "^5.1.1"
}
},
+ "parse-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+ "requires": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
"parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
@@ -37091,6 +37455,11 @@
}
}
},
+ "prismjs": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
+ "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
+ },
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -37165,6 +37534,14 @@
"signal-exit": "^3.0.2"
}
},
+ "property-information": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+ "requires": {
+ "xtend": "^4.0.0"
+ }
+ },
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -37965,6 +38342,18 @@
"react-is": "^16.12.0 || ^17.0.0"
}
},
+ "react-syntax-highlighter": {
+ "version": "15.5.0",
+ "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
+ "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "highlight.js": "^10.4.1",
+ "lowlight": "^1.17.0",
+ "prismjs": "^1.27.0",
+ "refractor": "^3.6.0"
+ }
+ },
"react-test-renderer": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz",
@@ -38088,6 +38477,16 @@
}
}
},
+ "refractor": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
+ "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
+ "requires": {
+ "hastscript": "^6.0.0",
+ "parse-entities": "^2.0.0",
+ "prismjs": "~1.27.0"
+ }
+ },
"regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -38924,6 +39323,11 @@
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw=="
},
+ "space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="
+ },
"split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
diff --git a/package.json b/package.json
index 04754af81..6c067883f 100644
--- a/package.json
+++ b/package.json
@@ -82,6 +82,7 @@
"react-native-video": "5.2.0",
"react-native-webview": "11.18.1",
"react-native-youtube": "2.0.2",
+ "react-syntax-highlighter": "15.5.0",
"reanimated-bottom-sheet": "1.0.0-alpha.22",
"rn-placeholder": "3.0.3",
"semver": "7.3.6",
@@ -117,6 +118,7 @@
"@types/react-native-button": "3.0.1",
"@types/react-native-share": "3.3.3",
"@types/react-native-video": "5.0.13",
+ "@types/react-syntax-highlighter": "13.5.2",
"@types/react-test-renderer": "17.0.1",
"@types/semver": "7.3.9",
"@types/shallow-equals": "1.0.0",
diff --git a/patches/@types+react-syntax-highlighter+13.5.2.patch b/patches/@types+react-syntax-highlighter+13.5.2.patch
new file mode 100644
index 000000000..0122ba288
--- /dev/null
+++ b/patches/@types+react-syntax-highlighter+13.5.2.patch
@@ -0,0 +1,15 @@
+diff --git a/node_modules/@types/react-syntax-highlighter/index.d.ts b/node_modules/@types/react-syntax-highlighter/index.d.ts
+index 6ee9af3..cf1516e 100755
+--- a/node_modules/@types/react-syntax-highlighter/index.d.ts
++++ b/node_modules/@types/react-syntax-highlighter/index.d.ts
+@@ -33,6 +33,10 @@ declare module 'react-syntax-highlighter' {
+ export { default as Prism } from 'react-syntax-highlighter/dist/esm/prism';
+ }
+
++declare module 'react-syntax-highlighter/create-element' {
++ export {createStyleObject} from 'react-syntax-highlighter/create-element';
++}
++
+ // esm start
+ declare module 'react-syntax-highlighter/dist/esm/default-highlight' {
+ import * as React from 'react';
diff --git a/patches/react-syntax-highlighter+15.5.0.patch b/patches/react-syntax-highlighter+15.5.0.patch
new file mode 100644
index 000000000..ecc3b8514
--- /dev/null
+++ b/patches/react-syntax-highlighter+15.5.0.patch
@@ -0,0 +1,7 @@
+diff --git a/node_modules/react-syntax-highlighter/create-element.js b/node_modules/react-syntax-highlighter/create-element.js
+index 76d3cf2..1951d6c 100644
+--- a/node_modules/react-syntax-highlighter/create-element.js
++++ b/node_modules/react-syntax-highlighter/create-element.js
+@@ -1 +1 @@
+-export { default } from './dist/esm/create-element';
++export { default, createStyleObject } from './dist/esm/create-element';