{"version":3,"file":"static/js/480.4f3efb83.chunk.js","mappings":"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","sources":["components/admin/TextareaForm.js","constants/Colors.js","utils/parser.js","utils/FormattedBlockText.js","utils/reportError.js"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport injectSheet from 'react-jss';\nimport { GREY_A, GREY_E } from '../../constants/Colors';\nimport FormattedBlockText from '../../utils/FormattedBlockText';\nimport bindMethods from '../../utils/bindMethods';\n\nconst jssStyles = {\n  wrap: (props) => ({\n    width: '100%',\n    display: 'flex',\n    flexDirection: props?.textareaData?.noWrap ? 'column' : 'row',\n    gap: '10px',\n  }),\n  textarea: {\n    width: '100%',\n    padding: '10px',\n    boxSizing: 'border-box',\n  },\n  preview: {\n    width: '100%',\n    boxSizing: 'border-box',\n    padding: '10px 20px',\n    backgroundColor: '#fff',\n    border: '1px solid',\n    borderColor: GREY_E,\n    borderRadius: '3px',\n  },\n  instructions: {\n    marginTop: '10px',\n  },\n  tag: {\n    display: 'inline-block',\n    padding: '4px 6px',\n    margin: '0 5px 5px 0',\n    borderColor: GREY_E,\n    borderRadius: '3px',\n    border: '1px solid',\n    color: GREY_A,\n    fontSize: '11px',\n    lineHeight: 1,\n  },\n};\n\nclass TextareaForm extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      formText: this.props.initialTextData ?? '',\n    };\n    this.bound = bindMethods(this, ['onChangeText']);\n  }\n\n  onChangeText(e) {\n    this.setState({\n      formText: e.target.value,\n    });\n  }\n\n  render() {\n    const {\n      classes,\n      textareaData: {\n        name,\n        cols,\n        rows,\n        required,\n        placeholder,\n      } = {},\n    } = this.props;\n    return (\n      <div>\n        <div className={classes.wrap}>\n          <textarea\n            value={this.state.formText}\n            name={name}\n            cols={cols}\n            rows={rows}\n            required={required}\n            onChange={this.bound.onChangeText}\n            className={classes.textarea}\n            data-testid=\"text-area\"\n            placeholder={placeholder ?? ''}\n          />\n          <div className={classes.preview}>\n            <FormattedBlockText\n              text={this.state.formText}\n              showError\n            />\n          </div>\n        </div>\n        <div className={classes.instructions}>\n          <span className={classes.tag}>*bold*</span>\n          <span className={classes.tag}>_italic_</span>\n          <span className={classes.tag}>~~del~~</span>\n          <span className={classes.tag}>* list</span>\n          <span className={classes.tag}>1. no list</span>\n          <span className={classes.tag}>http://url/ becomes &lt;a href=&quot;http://url/&quot;&gt;http://url/&lt;/a&gt;</span>\n          <span className={classes.tag}>custom link: [label](http://url/) to open in new tab</span>\n          <span className={classes.tag}>img tag: ![](http://url/)</span>\n        </div>\n      </div>\n    );\n  }\n}\n\nTextareaForm.propTypes = {\n  initialTextData: PropTypes.string,\n  textareaData: PropTypes.shape({\n    name: PropTypes.string,\n    cols: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n    rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n    required: PropTypes.string,\n    noWrap: PropTypes.bool,\n    placeholder: PropTypes.string,\n  }),\n  classes: PropTypes.object.isRequired,\n};\n\nexport default injectSheet(jssStyles)(TextareaForm);\n","export const PURE_WHITE = '#fff';\nexport const PURE_BLACK = '#000';\n\nexport const GREY_A = '#808080';\nexport const GREY_B = '#b3b3b3';\nexport const GREY_C = '#ccc';\nexport const GREY_D = '#d8d8d8';\nexport const GREY_E = '#eee';\nexport const GREY_F = '#f2f2f2';\nexport const GREY_G = '#333';\nexport const GREY_H = '#787878';\nexport const GREY_I = '#404040';\n\nexport const RED_A = '#e3463d';\nexport const BLUE_A = '#4bbcff';\nexport const BLUE_B = '#43aae6';\nexport const BLUE_C = '#009DFF';\nexport const BLUE_D = '#5ec0ff';\nexport const ORANGE_A = '#ef871a';\n\nexport const YELLOW_A = '#ebc56a';\nexport const YELLOW_B = '#FFF3AB';\nexport const YELLOW_C = '#FFE539';\nexport const YELLOW_D = '#FFF9D5';\n","import React from 'react';\nimport {\n  defaultRules,\n  inlineRegex,\n  sanitizeUrl,\n  parserFor,\n  ruleOutput,\n  reactFor,\n} from 'simple-markdown';\n\n// Matches all non-newline characters, followed by special characters, newlines, URLs, or the end of\n// the string (which should match all of the other rules).\nconst TEXT_MATCH = /^[^\\n]+?(?=[^0-9A-Za-z\\s\\u00c0-\\uffff]|\\n|\\w+:\\S|$)/;\n\nconst customRules = {\n  // Don't use those rules from defaultRules\n  // heading: defaultRules.heading,\n  // nptable: defaultRules.nptable,\n  // lheading: defaultRules.lheading,\n  // hr: defaultRules.hr,\n  // inlineCode: defaultRules.inlineCode,\n  // codeBlock: defaultRules.codeBlock,\n  // fence: defaultRules.fence,\n  // blockQuote: defaultRules.blockQuote,\n  // def: defaultRules.def,\n  // table: defaultRules.table,\n  // autolink: defaultRules.autolink,\n  // mailto: defaultRules.mailto,\n  // reflink: defaultRules.reflink,\n  // refimage: defaultRules.refimage,\n  // newline: defaultRules.newline,\n  // escape: defaultRules.escape,\n\n  // Custom rules for chat-style markup:\n  // simple-markdown outputs a <div> instead of a <p> by default.\n  // so we change the paragraph rule.\n  paragraph: {\n    ...defaultRules.paragraph,\n    react: (node, output, state) => (\n      <p key={state.key}>{output(node.content, state)}</p>\n    ),\n  },\n  // Automatically convert URLs to <a> tags.\n  url: defaultRules.url,\n  // custom [link](http://url/) to open in new tab\n  link: {\n    ...defaultRules.link,\n    react: (node, output, state) => (\n      <a\n        key={state.key}\n        href={sanitizeUrl(node.target)}\n        target=\"_blank\"\n      >\n        {output(node.content, state)}\n      </a>\n    ),\n  },\n  // img tags ![](http://url/)\n  image: defaultRules.image,\n  // _italic_\n  simpleItalic: {\n    ...defaultRules.em,\n    match: inlineRegex(/^_([\\s\\S]+?)_(?!_)/),\n  },\n  // *bold*\n  simpleBold: {\n    ...defaultRules.strong,\n    match: inlineRegex(/^\\*([\\s\\S]+?)\\*(?!\\*)/),\n  },\n  // ~~strikethrough~~\n  del: defaultRules.del,\n  // * list \\n\\n\n  // 1. no list \\n\\n\n  list: defaultRules.list,\n  // Convert newlines to <br>.\n  br: {\n    ...defaultRules.br,\n    match: (source) => /^\\n/.exec(source),\n    react: (node, output, state) => <br key={state.key} />,\n  },\n  // Parse plain text, but don't eat newlines that aren't preceded by two spaces or another newline\n  // like defaultRules.text does, because we want to allow single newlines to be converted to <br>\n  // tags without requiring two spaces at the end of the line like Markdown.\n  //\n  // NOTE: With simple-markdown the `text` rule must match anything that none of your other rules\n  // should match or else parsing might fail with an error that no rules matched the text. This\n  // means that you might have to update the regex for `text` any time you update another rule,\n  // making it potentially difficult to maintain.\n  text: {\n    ...defaultRules.text,\n    match: inlineRegex(TEXT_MATCH),\n  },\n  // NOTE: the br and text rules should always both appear at the end of any parsers made with these\n  // rules, so the br rule can \"eat\" all newlines and the text rule can eat all other characters. If\n  // these rules aren't included, then there may be no rules to fall back on and parsing may fail.\n};\n\nexport const markupParser = parserFor(customRules);\n\nexport const reactRenderer = reactFor(ruleOutput(customRules, 'react'));\n","import PropTypes from 'prop-types';\nimport React from 'react';\nimport injectSheet from 'react-jss';\nimport {\n  BLUE_A,\n  BLUE_B,\n} from '../constants/Colors';\nimport { reportError } from './reportError';\nimport { markupParser, reactRenderer } from './parser';\n\nconst jssStyles = {\n  default: {\n    '& p': {\n      margin: '1em 0',\n    },\n    '& img': {\n      maxWidth: '100%',\n      height: 'auto',\n      margin: '1em 0',\n      verticalAlign: 'bottom',\n    },\n    '& em': {\n      fontWeight: 'normal',\n      fontStyle: 'italic',\n    },\n    '& strong': {\n      fontWeight: 'bold',\n      fontStyle: 'normal',\n    },\n    '& a': {\n      color: BLUE_A,\n    },\n    '& a:hover': {\n      color: BLUE_B,\n    },\n    '& ul': {\n      paddingLeft: '1.5em',\n      margin: '1em 0',\n      listStyleType: 'disc',\n    },\n    '& ol': {\n      paddingLeft: '1.5em',\n      margin: '1em 0',\n      listStyleType: 'decimal',\n    },\n  },\n};\n\nconst FormattedBlockText = ({\n  text,\n  classes,\n  showError = false,\n}) => {\n  try {\n    // “Note that since many rules expect blocks to end in \"\\n\\n\",\n    // we append that to source input manually,\n    // in addition to specifying inline: false (inline: false is technically optional\n    // for all of the default rules, which assume inline is false if it is undefined).”\n    // Source: https://github.com/Khan/simple-markdown#putting-it-all-together\n    const parseTree = markupParser(`${text}\\n\\n`, { inline: false });\n    const outputResult = reactRenderer(parseTree);\n    return (\n      <div\n        className={classes.default}\n        data-testid=\"formatted-block-text\"\n      >\n        {outputResult}\n      </div>\n    );\n  } catch (error) {\n    if (showError) {\n      const errormessage = `RenderFormattedText received invalid rules: ${error}`;\n      reportError(error);\n      return (\n        <div\n          className={classes.default}\n          data-testid=\"formatted-block-text\"\n        >\n          {errormessage}\n        </div>\n      );\n    } else {\n      return (\n        <div\n          className={classes.default}\n          data-testid=\"formatted-block-text\"\n        >\n          {text}\n        </div>\n      );\n    }\n  }\n};\n\nFormattedBlockText.propTypes = {\n  text: PropTypes.string.isRequired,\n  classes: PropTypes.object.isRequired,\n  showError: PropTypes.bool,\n};\n\nexport default injectSheet(jssStyles)(FormattedBlockText);\n","// TODO: Remove the belong line\n// should add error reporting service\n\n/* istanbul ignore next */\nexport const reportError = (error) =>\n  process.env.NODE_ENV !== 'test' && console.error(error); // eslint-disable-line no-console\n"],"names":["jssStyles","wrap","props","_props$textareaData","width","display","flexDirection","textareaData","noWrap","gap","textarea","padding","boxSizing","preview","backgroundColor","border","borderColor","GREY_E","borderRadius","instructions","marginTop","tag","margin","color","GREY_A","fontSize","lineHeight","TextareaForm","React","constructor","_this$props$initialTe","super","this","state","formText","initialTextData","bound","bindMethods","onChangeText","e","setState","target","value","render","classes","name","cols","rows","required","placeholder","_jsxs","children","className","_jsx","onChange","FormattedBlockText","text","showError","injectSheet","PURE_WHITE","GREY_B","GREY_C","GREY_D","GREY_F","GREY_G","GREY_H","GREY_I","RED_A","BLUE_A","BLUE_B","BLUE_C","ORANGE_A","YELLOW_A","YELLOW_C","YELLOW_D","customRules","paragraph","defaultRules","react","node","output","content","key","url","link","href","sanitizeUrl","image","simpleItalic","em","match","inlineRegex","simpleBold","strong","del","list","br","source","exec","markupParser","parserFor","reactRenderer","reactFor","ruleOutput","default","maxWidth","height","verticalAlign","fontWeight","fontStyle","paddingLeft","listStyleType","_ref","parseTree","concat","inline","outputResult","error","errormessage","reportError","console"],"sourceRoot":""}