{"version":3,"sources":["webpack:///./node_modules/preact/dist/preact.module.js","webpack:///./app/javascript/common-prop-types/default-children-prop-types.js","webpack:///./app/javascript/Snackbar/index.js","webpack:///./app/javascript/utilities/viewport.js","webpack:///./app/javascript/utilities/dropdownUtils.js","webpack:///./app/javascript/utilities/debounceAction.js","webpack:///./app/javascript/shared/components/useKeyboardShortcuts.js","webpack:///./app/javascript/utilities/showModal.jsx","webpack:///./app/javascript/packs/validateFileInputs.js","webpack:///./node_modules/ahoy.js/dist/ahoy.esm.js","webpack:///./app/javascript/utilities/getUserDataAndCsrfToken.js","webpack:///./app/javascript/Snackbar/SnackbarItem.jsx","webpack:///./node_modules/moment/locale sync ^\\.\\/.*$","webpack:///./app/javascript/shared/components/focusTrap.jsx","webpack:///./app/javascript/crayons/Modal/Modal.jsx","webpack:///./app/javascript/utilities/gist.js","webpack:///./app/javascript/article-form/actions.js","webpack:///./app/javascript/common-prop-types/article-prop-types.js","webpack:///./app/javascript/utilities/calculateTextAreaHeight.js","webpack:///./app/javascript/utilities/textAreaUtils.js","webpack:///./app/javascript/crayons/Button/index.js","webpack:///./app/javascript/crayons/Button/Button.jsx","webpack:///./app/javascript/crayons/Spinner/Spinner.jsx","webpack:///./app/javascript/Snackbar/Snackbar.jsx","webpack:///./app/javascript/crayons/AutocompleteTriggerTextArea/UserListItemContent.jsx","webpack:///./app/javascript/crayons/AutocompleteTriggerTextArea/AutocompleteTriggerTextArea.jsx","webpack:///./app/javascript/article-form/components/ClipboardButton.jsx","webpack:///./app/javascript/article-form/components/ImageUploader.jsx","webpack:///./app/javascript/utilities/ahoy/trackEvents.jsx","webpack:///./app/javascript/crayons/Buttons/Button.jsx","webpack:///./app/javascript/crayons/Links/Link.jsx","webpack:///./app/javascript/crayons/CTAs/CTA.jsx","webpack:///./app/javascript/crayons/ButtonGroup/ButtonGroup.jsx","webpack:///./app/javascript/crayons/Dropdown/Dropdown.jsx","webpack:///./app/javascript/crayons/formElements/FormField/FormField.jsx","webpack:///./app/javascript/crayons/formElements/RadioButton/RadioButton.jsx","webpack:///./app/javascript/crayons/formElements/ColorPicker/ColorPicker.jsx","webpack:///./app/javascript/crayons/formElements/Toggles/Toggle.jsx","webpack:///./app/javascript/crayons/formElements/DateRangePicker/dateRangeUtils.js","webpack:///./app/javascript/crayons/formElements/DateRangePicker/DateRangePicker.jsx","webpack:///./app/javascript/crayons/Icons/Icon.jsx","webpack:///./app/javascript/crayons/MobileDrawer/MobileDrawer.jsx","webpack:///./app/javascript/crayons/MarkdownToolbar/markdownSyntaxFormatters.jsx","webpack:///./app/javascript/crayons/MarkdownToolbar/MarkdownToolbar.jsx","webpack:///./app/javascript/shared/components/defaultSelectionTemplate.jsx","webpack:///./app/javascript/crayons/MultiSelectAutocomplete/MultiSelectAutocomplete.jsx","webpack:///./app/javascript/utilities/codeFullscreenModeSwitcher.js","webpack:///./app/javascript/common-prop-types/user-prop-types.js","webpack:///./app/javascript/common-prop-types/selected-tags-prop-types.js","webpack:///./app/javascript/liquidTags/userSubscriptionLiquidTag.js","webpack:///./app/javascript/packs/articlePage.jsx","webpack:///./app/javascript/utilities/runtime.js","webpack:///./app/javascript/shared/components/useMediaQuery.js"],"names":["n","l","u","i","t","r","o","f","e","c","s","a","h","v","parentNode","removeChild","y","arguments","length","children","call","defaultProps","p","type","props","key","ref","__k","__","__b","__e","__d","__c","__h","constructor","__v","vnode","d","current","_","b","setProperty","test","g","style","cssText","replace","toLowerCase","slice","addEventListener","w","m","removeEventListener","indexOf","removeAttribute","setAttribute","this","event","x","context","A","P","base","C","setTimeout","T","push","$","__r","debounceRendering","sort","shift","__P","M","__n","ownerSVGElement","N","H","k","Array","isArray","I","z","L","nextSibling","q","S","j","some","appendChild","insertBefore","contextType","value","__E","prototype","render","B","sub","state","_sb","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","forEach","componentWillUpdate","componentDidUpdate","getChildContext","getSnapshotBeforeUpdate","O","diffed","localName","nodeType","document","createTextNode","createElementNS","createElement","is","data","childNodes","dangerouslySetInnerHTML","attributes","name","__html","innerHTML","checked","unmount","componentWillUnmount","D","firstChild","E","F","G","Consumer","Provider","splice","getDerivedStateFromError","setState","componentDidCatch","forceUpdate","Promise","then","bind","resolve","defaultChildrenPropTypes","PropTypes","oneOfType","arrayOf","node","object","isInViewport","element","offsetTop","allowPartialVisibility","boundingRect","getBoundingClientRect","clientHeight","window","innerHeight","documentElement","clientWidth","innerWidth","topIsInViewport","top","rightIsInViewport","right","bottomIsInViewport","bottom","leftIsInViewport","left","topIsOutOfViewport","bottomIsOutOfViewport","getDropdownRepositionListener","debounceAction","handleDropdownRepositions","querySelectorAll","classList","remove","isDropdownCurrentlyOpen","display","opacity","add","removeProperty","INTERACTIVE_ELEMENTS_QUERY","openDropdown","triggerElementId","dropdownContentId","dropdownContent","getElementById","querySelector","focus","closeDropdown","onClose","initializeDropdown","dropdownContentCloseButtonId","onOpen","triggerButton","keyUpListener","getAttribute","onCloseCleanupActions","contains","activeElement","clickOutsideListener","target","matches","action","time","config","leading","configs","debounce","isFormField","HTMLElement","nodeName","isContentEditable","callShortcut","keys","chain","shortcuts","shortcut","join","code","defaultOptions","timeout","useKeyboardShortcuts","eventTarget","options","useState","storedShortcuts","keyChain","setKeyChain","mergedOptions","setMergedOptions","useEffect","newOptions","clearTimeout","Object","keyEvent","defaultPrevented","ctrlKeyEntry","ctrlKey","cmdKeyEntry","metaKey","altKeyEntry","altKey","shiftKeyEntry","shiftKey","Node","newChain","KeyboardShortcuts","propTypes","isRequired","shape","number","instanceOf","Element","Window","preactImport","modalImports","WINDOW_MODAL_ID","getPreactImport","showWindowModal","modalContent","contentSelector","modalProps","all","Modal","currentModalContainer","body","focusTrapSelector","className","closeWindowModal","MAX_FILE_SIZE_MB","freeze","image","video","PERMITTED_FILE_TYPES","addErrorMessage","msg","addSnackbarItem","message","addCloseButton","validateFileSize","file","fileType","fileInput","maxFileSizeMb","dataset","fileSizeErrorHandler","fileSizeMb","size","toFixed","isValidFileSize","Number","errorMessage","handleFileSizeError","validateFileType","permittedFileTypes","JSON","parse","fileTypeErrorHandler","isValidFileType","includes","fileTypeBracketed","handleFileTypeError","validateFileNameLength","maxFileNameLength","fileNameLengthErrorHandler","isValidFileNameLength","handleFileNameLengthError","validateFileInput","isValidFileInput","files","from","split","validateFileInputs","validFileInputs","fileInputs","Cookies","ttl","domain","expires","cookieDomain","date","Date","setTime","getTime","toGMTString","cookie","escape","nameEQ","ca","charAt","substring","unescape","urlPrefix","visitsUrl","eventsUrl","page","platform","useBeacon","startOnReady","trackVisits","cookies","headers","visitParams","withCredentials","visitDuration","visitorDuration","ahoy","Ahoy","configure","hasOwnProperty","visitId","visitorId","track","callback","jQuery","Zepto","isReady","queue","canStringify","eventQueue","canTrackNow","trackNow","obj","navigator","setCookie","getCookie","destroyCookie","log","console","setReady","matchesSelector","selector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","apply","parentElement","onEvent","eventName","matchedElement","skip","getClosest","generateId","Math","random","toString","saveEventQueue","stringify","csrfToken","meta","content","CSRFProtection","xhr","token","setRequestHeader","sendRequest","url","success","ajax","contentType","dataType","beforeSend","xhrFields","XMLHttpRequest","header","open","onload","status","send","eventData","events","visit_token","visitor_token","trackEvent","ready","id","trackEventNow","param","events_json","sendBeacon","FormData","append","serialize","location","pathname","presence","str","eventProperties","cleanObject","tag","tagName","section","attribute","hasAttribute","createVisit","getVisitId","getVisitorId","landing_page","href","screen_width","screen","width","screen_height","height","js","referrer","visitParam","getVisitToken","getVisitorToken","reset","debug","enabled","properties","trackView","additionalProperties","title","propName","trackClicks","undefined","Error","text","textContent","innerText","trim","trackSubmits","trackChanges","start","readyState","getWaitOnUserDataHandler","reject","waitTime","totalTimeWaiting","waitingOnUserData","user","currentUser","getUserDataAndCsrfToken","snackbarItemProps","actions","string","handler","func","lifespan","SnackbarItem","role","map","variant","inverted","onClick","displayName","webpackContext","req","webpackContextResolve","__webpack_require__","module","exports","FocusTrap","onDeactivate","clickOutsideDeactivates","focusTrap","useRef","deactivate","useCallback","useLayoutEffect","currentLocationHref","routeChangeObserver","MutationObserver","mutations","disconnect","createFocusTrap","escapeDeactivates","activate","observe","childList","CloseIcon","prompt","sheet","centered","noBackdrop","showHeader","sheetAlign","backdropDismissible","allowOverflow","classes","classNames","class","icon","backdrop","bool","oneOf","postscribeImport","getPostScribe","postscribe","getGistTags","nodes","gistNodes","loadEmbeddedGists","gistTags","gistTag","gistWrapper","firstElementChild","outerHTML","beforeWrite","childElementCount","watchForGistTagInsertion","targetNode","observer","mutationsList","addedNodes","subtree","InstantClick","on","embedGists","previewArticle","payload","successCb","failureCb","fetch","method","Accept","article_body","credentials","response","json","processPayload","previewShowing","helpShowing","previewResponse","helpHTML","imageManagementShowing","moreConfigShowing","errors","submitArticle","onSuccess","onError","article","current_state_path","generateUploadFormdata","formData","entries","generateMainImage","signal","error","links","processImageUpload","images","handleImageUploading","handleImageSuccess","handleImageFailure","articleSnippetResultPropTypes","body_text","articlePropTypes","path","cloudinary_video_url","video_duration_in_minutes","type_of","class_name","flare_tag","bg_color_hex","text_color_hex","tag_list","cached_tag_list_array","podcast","slug","image_url","user_id","username","organization","profile_image_90","highlight","public_reactions_count","reactions_count","comments_count","reading_time","hiddenTextarea","SIZING_STYLE","calculateNodeStyling","getComputedStyle","boxSizing","getPropertyValue","paddingSize","parseFloat","borderSize","sizingStyle","getCursorXY","input","selectionPoint","relativeToElement","bodyRect","elementRect","inputY","scrollTop","inputX","scrollLeft","div","copyStyle","values","property","inputValue","substr","span","spanX","offsetLeft","spanY","getAutocompleteWordData","textArea","triggerCharacter","selectionStart","valueBeforeKeystroke","isTriggered","indexOfAutocompleteStart","getLastIndexOfCharacter","selectionIndex","character","breakOnCharacters","currentCharacter","previousCharacter","getNextIndexOfCharacter","nextCharacter","getNumberOfNewLinesPrecedingSelection","count","searchIndex","getNumberOfNewLinesFollowingSelection","selectionEnd","getSelectionData","textBeforeSelection","textAfterSelection","selectedText","useTextAreaAutoResize","setTextArea","constrainToContentHeight","setConstrainToContentHeight","additionalElements","setAdditionalElements","resizeTextArea","allElements","allContentHeights","uiTextNode","placeholder","baseHeight","scrollHeight","calculateTextAreaHeight","max","newHeight","resizeCallback","resizeObserver","ResizeObserver","getAdditionalClassNames","disabled","tooltip","additionalClassNames","Button","buttonType","onMouseOver","onMouseOut","onFocus","onBlur","onKeyUp","tabIndex","restOfProps","suppressTooltip","setSuppressTooltip","ComponentName","Icon","otherProps","Spinner","viewBox","fill","xmlns","snackbarItems","snackbarItem","Snackbar","snacks","pollingId","paused","pauseLifespan","resumeLifespan","initializePolling","_event","stopPropagation","pollingTime","setInterval","newSnacks","updateSnackbarItems","snack","lifespanTimeoutId","decreaseLifespan","prevState","filter","potentialSnackToFilterOut","updatedSnacks","currentSnack","index","Component","UserListItemContent","src","alt","KEYS","reducer","isComboboxMode","suggestions","dropdownPositionPoints","activeDescendentIndex","suppressPopover","emptyStateMessage","ignoreBlur","AutocompleteTriggerTextArea","forwardRef","forwardedRef","autoResize","onChange","fetchSuggestions","searchInstructionsMessage","maxSuggestions","replaceElement","inputProps","useReducer","dispatch","isSmallScreen","useMediaQuery","BREAKPOINTS","Small","inputRef","popoverRef","wrapperRef","popover","activeItem","scrollIntoView","originalTextArea","newTextArea","enhancedTextArea","defaultView","attributeKey","transition","preventScroll","refs","selectSuggestion","suggestion","currentInput","indexOfSearchStart","currentSearchTerm","contentEditable","setSelectionRange","execCommand","currentValue","newTextAreaValue","comboboxProps","isSearching","searchTermStartPosition","searchTerm","cursorX","textAreaX","handleInputChange","onKeyDown","preventDefault","createPortal","onMouseDown","CopyIcon","ClipboardButton","imageLinks","onCopy","imageUrls","showCopyMessage","readOnly","imageLink","ImageIcon","CancelIcon","SpinnerOrCancel","imageUploaderReducer","uploadErrorMessage","uploadingImage","insertionImageUrls","initNativeImagePicker","ForemMobile","injectNativeMessage","NativeIosV1ImageUpload","V2EditorImageUpload","buttonProps","handleInsertionImageUpload","useNativeUpload","handleNativeMessage","abortRequestController","setAbortRequestController","actionTooltip","tabindex","controller","AbortController","accept","abort","click","V1EditorImageUpload","showCopiedImageText","setShowCopiedImageText","multiple","imageMarkdownInput","copyToClipboard","Honeybadger","notify","ImageUploader","editorVersion","onImageUploadStart","onImageUploadSuccess","onImageUploadError","onUploadError","abortSignal","handleInsertImageUploadSuccess","detail","namespace","link","isNativeIOS","trackCommentClicks","elementId","relevantNode","getTrackingNode","trackingName","trackCreateAccountClicks","version","source","trackingSource","trackingElement","closest","ButtonNew","rounded","destructive","focusable","elementType","Link","block","CTA","ButtonGroup","labelText","Dropdown","triggerButtonId","isInitialized","setIsInitialized","FormField","RadioButton","ColorPicker","buttonLabelText","defaultValue","color","setColor","buttonId","popoverId","backgroundColor","fullHexCode","hex","handleBlur","prefixed","Toggle","MONTH_UNTIL_TODAY","QUARTER_UNTIL_TODAY","YEAR_UNTIL_TODAY","LAST_FULL_MONTH","LAST_FULL_QUARTER","LAST_FULL_YEAR","ALL_PRESET_RANGES","RANGE_LABELS","PERIODS","getPeriodUntilToday","today","period","clone","startOf","end","getLastFullPeriod","subtract","endOf","getDateRangeStartAndEndDates","dateRangeName","ChevronLeft","ChevronRight","Calendar","PICKER_PHRASES","defaultPhrases","chooseAvailableStartDate","chooseAvailableEndDate","focusStartDate","invalidDateFormat","format","errorPrefix","dateTooLate","latestDate","dateTooEarly","earliestDate","MONTH_NAMES","toLocaleString","month","MonthYearPicker","earliestMoment","latestMoment","onMonthSelect","onYearSelect","selectedMonth","selectedYear","year","latestMonthIndex","availableMonths","yearsDiff","diff","years","PresetDateRangeOptions","presetRanges","onPresetSelected","presetsWithinPermittedDates","rangeStart","rangeEnd","isSameOrBefore","isSameOrAfter","rangeName","DateRangePicker","startDateId","endDateId","defaultStartDate","defaultEndDate","maxEndDate","minStartDate","onDatesChanged","startDateAriaLabel","endDateAriaLabel","todaysDate","START_DATE","focusedInput","setFocusedInput","moment","startMoment","setStartMoment","endMoment","setEndMoment","dateFormat","getCurrentLocale","useCompactLayout","Medium","startDateInput","setStartDateInput","endDateInput","setEndDateInput","startDateError","setStartDateError","endDateError","setEndDateError","setError","inputType","valueMoment","isValid","isBefore","isAfter","handleStartBlur","handleEndBlur","useDateRangeValidation","startDate","endDate","startDatePlaceholderText","endDatePlaceholderText","displayFormat","navPrev","navNext","minDate","maxDate","initialVisibleMonth","relevantDate","isMonthSameAsLatestMonth","customInputIcon","showDefaultInputIcon","inputIconPosition","ICON_BEFORE_POSITION","orientation","VERTICAL_ORIENTATION","HORIZONTAL_ORIENTATION","showClearDates","customArrowIcon","phrases","onFocusChange","isOutsideRange","isBetween","isDateOutsideOfRange","onDatesChange","toDate","small","renderMonthElement","renderCalendarInfo","maxStartDate","InternalIcon","native","MobileDrawer","BoldIcon","ItalicIcon","LinkIcon","OrderedListIcon","UnorderedListIcon","HeadingIcon","QuoteIcon","CodeIcon","CodeBlockIcon","EmbedIcon","UnderlineIcon","StrikethroughIcon","DividerIcon","ORDERED_LIST_ITEM_REGEX","MARKDOWN_LINK_REGEX","URL_PLACEHOLDER_TEXT","getNewLinePrefixSuffixes","numberOfNewLinesBeforeSelection","numberOfNewLinesFollowingSelection","numberOfNewLinesNeededAtStart","newLinesPrefix","String","padStart","newLinesSuffix","undoOrAddFormattingForInlineSyntax","prefix","suffix","prefixLength","suffixLength","editSelectionStart","editSelectionEnd","replaceSelectionWith","newCursorStart","newCursorEnd","undoOrAddFormattingForMultilineSyntax","linePrefix","blockPrefix","blockSuffix","formattedText","lastNewLine","lineStart","splitByNewLine","line","every","unformattedText","newLinePrefixLength","cursorStartBaseline","cursorStartBlockPrefixOffset","cursorStartLinePrefixOffset","markdownSyntaxFormatters","bold","label","getKeyboardShortcut","modifier","getOSKeyboardModifierKeyString","command","tooltipHint","toUpperCase","getFormatting","italic","startingText","basicFormattingForEmptySelection","indexOfLinkStructureEnd","urlText","handleLinkFormattingForEmptyTextSelection","startsWith","basicFormattingForLinkSelection","indexOfSyntaxOpen","textToReplaceMarkdown","handleLinkFormattingForUrlSelection","match","linkDescriptionEnd","linkText","handleUndoMarkdownLinkSelection","orderedList","newLineSuffixLength","newText","indexOfFullStop","formattedList","textChunk","unorderedList","heading","currentLineSelectionStart","indexOfFirstLineCharacter","currentHeadingIndex","adjustingHeading","cursorOffset","quote","codeBlock","embed","underline","strikethrough","divider","OverflowIcon","UPLOADING_IMAGE_PLACEHOLDER","MAX_CORE_FORMATTERS_BY_SCREEN_SIZE","MarkdownToolbar","textAreaId","additionalSecondaryToolbarElements","textAreaRef","overflowMenuOpen","setOverflowMenuOpen","storedCursorPosition","setStoredCursorPosition","smallScreen","largeScreen","Large","ExtraLarge","overflowMenuRows","additionalSecondaryItems","SecondaryItem","cloneElement","handleToolbarButtonKeyPress","keyboardShortcuts","fromEntries","syntaxName","insertSyntax","clickOutsideHandler","escapePressHandler","getElementsByClassName","isLargeScreen","nextButton","sibling","nextElementSibling","getNextMatchingSibling","previousButton","previousElementSibling","getPreviousMatchingSibling","firstButton","allButtons","lastButton","textAreaValue","getNewTextAreaValueWithEdits","dispatchEvent","Event","handleImageUploadEnd","imageMarkdown","currentTextAreaValue","indexOfPlaceholder","newTextValue","differenceInLength","numberOfCoreFormatters","coreSyntaxFormatters","secondarySyntaxFormatters","secondaryFormatterButtons","controlName","textWithPlaceholder","newCursorPosition","Close","DefaultSelectionTemplate","enableValidation","valid","buttonVariant","onEdit","onDeselect","ALLOWED_CHARS_REGEX","selectedItems","editValue","inputPosition","showMaxSelectionsReached","MultiSelectAutocomplete","showLabel","staticSuggestions","staticSuggestionsHeading","border","inputId","maxSelections","onSelectionsChanged","allowUserDefinedSelections","SuggestionTemplate","SelectionTemplate","inputSizerRef","selectedItemsRef","allowSelections","resizeInputToContentSize","cursorPosition","changeEvent","offsetHeight","popoverOffsetHeight","isBelow","scrollTo","selectByText","textValue","nextInputValue","keepSelecting","matchingSuggestion","find","selectItem","selectedItem","enterEditState","editItem","editItemIndex","deselectItem","exitEditState","results","item","clearInput","editPreviousSelectionIfExists","nextEditIndex","currentSelections","insertIndex","newSelections","listItem","selection","deselectedItem","selectionNode","allSelectedItemElements","defaultPosition","position","order","selectionsPlaceholder","inputPlaceholder","autocomplete","suggestionDisplayName","optionPropType","isFullScreenModeCodeOn","screenScroll","fullScreenWindow","onPressEscape","fullScreenModeControl","listenToKeyboardForEscape","listen","toggleOverflowForDocument","overflow","addFullScreenModeControl","elements","currentTarget","cloneNode","codeBlockControls","removeFullScreenModeControl","scrollY","userPropTypes","profile_image_url","summary","selectedTagsPropTypes","tags","onKeyPress","toggleSubscribeActionUI","tagContainer","showSubscribeAction","appleAuth","signedInUI","appleAuthUI","toggleSignedOutUI","showSignedOutUI","signedOutUI","updateProfileImagesUI","signedIn","profileImagesContainer","initSignedOutState","initSignedInState","showConfirmSubscribeModal","confirmSubscribe","toggleSignedInInstructionsUI","clearNotices","toggleSubmitButtonsState","articleId","subscriber","userData","user_subscription","source_type","source_id","subscriber_email","email","getCsrfToken","sendFetch","res","submitSubscription","allSubscriptionLiquidTags","showSubscribedNotices","updateNotices","submit","notice","isVisible","instructions","fetchSubscriptionStatus","params","URLSearchParams","ok","statusText","authorUsername","populateSubscriberProfileImage","profileImageSrc","profileImage","allUserSubLiquidTags","userStatus","isSubscriberAuthedWithApple","apple_auth","isSubscribed","is_subscribed","animatedImages","initializePausableAnimatedImages","fullscreenActionElements","snackZone","multiReactionDrawerTrigger","initialized","shareDropdownButton","isNativeAndroid","AndroidBridge","shareText","hidden","postUrlValue","root","isLoggedIn","getCommentSubscriptionStatus","setCommentSubscriptionStatus","CommentSubscription","subscriptionType","subscriptionRequestHandler","positionType","onSubscribe","onUnsubscribe","initializeUserSubscriptionLiquidTagContent","IntersectionObserver","entry","isIntersecting","hash","FocusEvent","currentContext","currentMedium","currentOS","userAgent","nativeCheck","webkit","messageHandlers","namespaceCheck","clipboard","writeText","hasOSSpecificModifier","KeyboardEvent","language","query","mediaQuery","matchMedia","setMatch","addListener","removeListener"],"mappings":"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","file":"js/articlePage-90a08e516ba33df9a473.chunk.js","sourcesContent":["var n,l,u,i,t,r,o,f,e,c={},s=[],a=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function h(n,l){for(var u in l)n[u]=l[u];return n}function v(n){var l=n.parentNode;l&&l.removeChild(n)}function y(l,u,i){var t,r,o,f={};for(o in u)\"key\"==o?t=u[o]:\"ref\"==o?r=u[o]:f[o]=u[o];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),\"function\"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===f[o]&&(f[o]=l.defaultProps[o]);return p(l,f,t,r,null)}function p(n,i,t,r,o){var f={type:n,props:i,key:t,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++u:o};return null==o&&null!=l.vnode&&l.vnode(f),f}function d(){return{current:null}}function _(n){return n.children}function k(n,l,u,i,t){var r;for(r in u)\"children\"===r||\"key\"===r||r in l||g(n,r,null,u[r],i);for(r in l)t&&\"function\"!=typeof l[r]||\"children\"===r||\"key\"===r||\"value\"===r||\"checked\"===r||u[r]===l[r]||g(n,r,l[r],u[r],i)}function b(n,l,u){\"-\"===l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||a.test(l)?u:u+\"px\"}function g(n,l,u,i,t){var r;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof i&&(n.style.cssText=i=\"\"),i)for(l in i)u&&l in u||b(n.style,l,\"\");if(u)for(l in u)i&&u[l]===i[l]||b(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])r=l!==(l=l.replace(/Capture$/,\"\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?i||n.addEventListener(l,r?w:m,r):n.removeEventListener(l,r?w:m,r);else if(\"dangerouslySetInnerHTML\"!==l){if(t)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!==l&&\"height\"!==l&&\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&-1==l.indexOf(\"-\")?n.removeAttribute(l):n.setAttribute(l,u))}}function m(n){t=!0;try{return this.l[n.type+!1](l.event?l.event(n):n)}finally{t=!1}}function w(n){t=!0;try{return this.l[n.type+!0](l.event?l.event(n):n)}finally{t=!1}}function x(n,l){this.props=n,this.context=l}function A(n,l){if(null==l)return n.__?A(n.__,n.__.__k.indexOf(n)+1):null;for(var u;ll&&r.sort(function(n,l){return n.__v.__b-l.__v.__b}));$.__r=0}function H(n,l,u,i,t,r,o,f,e,a){var h,v,y,d,k,b,g,m=i&&i.__k||s,w=m.length;for(u.__k=[],h=0;h0?p(d.type,d.props,d.key,d.ref?d.ref:null,d.__v):d)){if(d.__=u,d.__b=u.__b+1,null===(y=m[h])||y&&d.key==y.key&&d.type===y.type)m[h]=void 0;else for(v=0;v=0;l--)if((u=n.__k[l])&&(i=L(u)))return i;return null}function M(n,u,i,t,r,o,f,e,c){var s,a,v,y,p,d,k,b,g,m,w,A,P,C,T,$=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,o=[e]),(s=l.__b)&&s(u);try{n:if(\"function\"==typeof $){if(b=u.props,g=(s=$.contextType)&&t[s.__c],m=s?g?g.props.value:s.__:t,i.__c?k=(a=u.__c=i.__c).__=a.__E:(\"prototype\"in $&&$.prototype.render?u.__c=a=new $(b,m):(u.__c=a=new x(b,m),a.constructor=$,a.render=B),g&&g.sub(a),a.props=b,a.state||(a.state={}),a.context=m,a.__n=t,v=a.__d=!0,a.__h=[],a._sb=[]),null==a.__s&&(a.__s=a.state),null!=$.getDerivedStateFromProps&&(a.__s==a.state&&(a.__s=h({},a.__s)),h(a.__s,$.getDerivedStateFromProps(b,a.__s))),y=a.props,p=a.state,a.__v=u,v)null==$.getDerivedStateFromProps&&null!=a.componentWillMount&&a.componentWillMount(),null!=a.componentDidMount&&a.__h.push(a.componentDidMount);else{if(null==$.getDerivedStateFromProps&&b!==y&&null!=a.componentWillReceiveProps&&a.componentWillReceiveProps(b,m),!a.__e&&null!=a.shouldComponentUpdate&&!1===a.shouldComponentUpdate(b,a.__s,m)||u.__v===i.__v){for(u.__v!==i.__v&&(a.props=b,a.state=a.__s,a.__d=!1),u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u)}),w=0;w2&&(f.children=arguments.length>3?n.call(arguments,2):i),p(l.type,f,t||l.key,r||l.ref,null)}function G(n,l){var u={__c:l=\"__cC\"+e++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(function(n){n.__e=!0,T(n)})},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=s.slice,l={__e:function(n,l,u,i){for(var t,r,o;l=l.__;)if((t=l.__c)&&!t.__)try{if((r=t.constructor)&&null!=r.getDerivedStateFromError&&(t.setState(r.getDerivedStateFromError(n)),o=t.__d),null!=t.componentDidCatch&&(t.componentDidCatch(n,i||{}),o=t.__d),o)return t.__E=t}catch(l){n=l}throw n}},u=0,i=function(n){return null!=n&&void 0===n.constructor},t=!1,x.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=h({},this.state),\"function\"==typeof n&&(n=n(h({},u),this.props)),n&&h(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),T(this))},x.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),T(this))},x.prototype.render=_,r=[],f=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,$.__r=0,e=0;export{x as Component,_ as Fragment,F as cloneElement,G as createContext,y as createElement,d as createRef,y as h,E as hydrate,i as isValidElement,l as options,D as render,j as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","import PropTypes from 'prop-types';\n\n// Use this whenever you need the standard children prop.\nexport const defaultChildrenPropTypes = PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n PropTypes.object,\n PropTypes.arrayOf(PropTypes.object),\n]);\n","export * from './Snackbar';\nexport * from './SnackbarItem';\n","/**\n * Checks if an element is visible in the viewport\n *\n * @example\n * const element = document.getElementById('element');\n * isInViewport({element, allowPartialVisibility = true}); // true or false\n *\n * @param {HTMLElement} element - The HTML element to check\n * @param {number} [offsetTop=0] - Part of the screen to ignore counting from the top\n * @param {boolean} [allowPartialVisibility=false] - A boolean to flip the check between partial or completely visible in the viewport\n * @returns {boolean} isInViewport - true if the element is visible in the viewport\n */\nexport function isInViewport({\n element,\n offsetTop = 0,\n allowPartialVisibility = false,\n}) {\n const boundingRect = element.getBoundingClientRect();\n const clientHeight =\n window.innerHeight || document.documentElement.clientHeight;\n const clientWidth = window.innerWidth || document.documentElement.clientWidth;\n const topIsInViewport =\n boundingRect.top <= clientHeight && boundingRect.top >= offsetTop;\n const rightIsInViewport =\n boundingRect.right >= 0 && boundingRect.right <= clientWidth;\n const bottomIsInViewport =\n boundingRect.bottom >= offsetTop && boundingRect.bottom <= clientHeight;\n const leftIsInViewport =\n boundingRect.left <= clientWidth && boundingRect.left >= 0;\n const topIsOutOfViewport = boundingRect.top <= offsetTop;\n const bottomIsOutOfViewport = boundingRect.bottom >= clientHeight;\n const elementSpansEntireViewport =\n topIsOutOfViewport && bottomIsOutOfViewport;\n\n if (allowPartialVisibility) {\n return (\n (topIsInViewport || bottomIsInViewport || elementSpansEntireViewport) &&\n (leftIsInViewport || rightIsInViewport)\n );\n }\n return (\n topIsInViewport &&\n bottomIsInViewport &&\n leftIsInViewport &&\n rightIsInViewport\n );\n}\n","import { isInViewport } from '@utilities/viewport';\nimport { debounceAction } from '@utilities/debounceAction';\n\n/**\n * Helper function designed to be used on scroll to detect when dropdowns should switch from dropping downwards/upwards.\n * The action is debounced since scroll events are usually fired several at a time.\n *\n * @returns {Function} a debounced function that handles the repositioning of dropdowns\n * @example\n *\n * document.addEventListener('scroll', getDropdownRepositionListener());\n */\nexport const getDropdownRepositionListener = () =>\n debounceAction(handleDropdownRepositions);\n\n/**\n * Checks for all dropdowns on the page which have the attribute 'data-repositioning-dropdown', signalling\n * they should dynamically change between dropping downwards or upwards, depending on viewport position.\n *\n * Any dropdowns not fully in view when dropping down will be switched to dropping upwards.\n */\nconst handleDropdownRepositions = () => {\n // Select all of the dropdowns which should reposition\n const allRepositioningDropdowns = document.querySelectorAll(\n '[data-repositioning-dropdown]',\n );\n\n for (const element of allRepositioningDropdowns) {\n // Default to dropping downwards\n element.classList.remove('reverse');\n\n const isDropdownCurrentlyOpen = element.style.display === 'block';\n\n if (!isDropdownCurrentlyOpen) {\n // We can't determine position on an element with display:none, so we \"show\" the dropdown with 0 opacity very temporarily\n element.style.opacity = 0;\n element.style.display = 'block';\n }\n\n if (!isInViewport({ element })) {\n // If the element isn't fully visible when dropping down, reverse the direction\n element.classList.add('reverse');\n }\n\n if (!isDropdownCurrentlyOpen) {\n // Revert the temporary changes to determine position\n element.style.removeProperty('display');\n element.style.removeProperty('opacity');\n }\n }\n};\n\n/**\n * Helper query string to identify interactive/focusable HTML elements\n */\nexport const INTERACTIVE_ELEMENTS_QUERY =\n 'button, [href], input:not([type=\"hidden\"]), select, textarea, [tabindex=\"0\"]';\n\n/**\n * Open the given dropdown, updating aria attributes, and focusing the first interactive element\n *\n * @param {Object} args\n * @param {string} args.triggerElementId The id of the button which activates the dropdown\n * @param {string} args.dropdownContent The id of the dropdown content element\n */\nexport const openDropdown = ({ triggerElementId, dropdownContentId }) => {\n const dropdownContent = document.getElementById(dropdownContentId);\n const triggerElement = document.getElementById(triggerElementId);\n\n triggerElement.setAttribute('aria-expanded', 'true');\n\n // Style set inline to prevent specificity issues\n dropdownContent.style.display = 'block';\n\n // Send focus to the first suitable element\n dropdownContent.querySelector(INTERACTIVE_ELEMENTS_QUERY)?.focus();\n};\n\n/**\n * Close the given dropdown, updating aria attributes\n *\n * @param {Object} args\n * @param {string} args.triggerElementId The id of the button which activates the dropdown\n * @param {string} args.dropdownContent The id of the dropdown content element\n * @param {Function} args.onClose Optional function for any side-effects which should occur on dropdown close\n */\nexport const closeDropdown = ({\n triggerElementId,\n dropdownContentId,\n onClose,\n}) => {\n const dropdownContent = document.getElementById(dropdownContentId);\n\n if (!dropdownContent) {\n // Component may have unmounted\n return;\n }\n\n document\n .getElementById(triggerElementId)\n ?.setAttribute('aria-expanded', 'false');\n\n // Remove the inline style added when we opened the dropdown\n dropdownContent.style.removeProperty('display');\n\n onClose?.();\n};\n\n/**\n * A helper function to initialize dropdown behaviors. This function attaches open/close click and keyup listeners,\n * and makes sure relevant aria properties and keyboard focus are updated.\n *\n * @param {Object} args\n * @param {string} args.triggerButtonElementId The ID of the button which triggers the dropdown open/close behavior\n * @param {string} args.dropdownContentId The ID of the dropdown content which should open/close on trigger button press\n * @param {string} args.dropdownContentCloseButtonId Optional ID of any button within the dropdown content which should close the dropdown\n * @param {Function} args.onClose An optional callback for when the dropdown is closed. This can be passed to execute any side-effects required when the dropdown closes.\n * @param {Function} args.onOpen An optional callback for when the dropdown is opened. This can be passed to execute any side-effects required when the dropdown opens.\n *\n * @returns {{closeDropdown: Function}} Object with callback to close the initialized dropdown\n */\nexport const initializeDropdown = ({\n triggerElementId,\n dropdownContentId,\n dropdownContentCloseButtonId,\n onClose,\n onOpen,\n}) => {\n const triggerButton = document.getElementById(triggerElementId);\n const dropdownContent = document.getElementById(dropdownContentId);\n\n if (!triggerButton || !dropdownContent) {\n // The required props haven't been provided, do nothing\n return;\n }\n\n // Ensure default values have been applied\n triggerButton.setAttribute('aria-expanded', 'false');\n triggerButton.setAttribute('aria-controls', dropdownContentId);\n triggerButton.setAttribute('aria-haspopup', 'true');\n\n const keyUpListener = ({ key }) => {\n if (key === 'Escape') {\n // Close the dropdown and return focus to the trigger button to prevent focus being lost\n const isCurrentlyOpen =\n triggerButton.getAttribute('aria-expanded') === 'true';\n if (isCurrentlyOpen) {\n closeDropdown({\n triggerElementId,\n dropdownContentId,\n onClose: onCloseCleanupActions,\n });\n triggerButton.focus();\n }\n } else if (key === 'Tab') {\n // Close the dropdown if the user has tabbed away from it\n const isInsideDropdown = dropdownContent?.contains(\n document.activeElement,\n );\n if (!isInsideDropdown) {\n closeDropdown({\n triggerElementId,\n dropdownContentId,\n onClose: onCloseCleanupActions,\n });\n }\n }\n };\n\n // Close the dropdown if user has clicked outside\n const clickOutsideListener = ({ target }) => {\n // Get fresh handle every time, resulting in more streamlined functionality for cypress\n const triggerButton = document.getElementById(triggerElementId);\n if (\n triggerButton &&\n target !== triggerButton &&\n !dropdownContent.contains(target) &&\n !triggerButton.contains(target)\n ) {\n closeDropdown({\n triggerElementId,\n dropdownContentId,\n onClose: onCloseCleanupActions,\n });\n\n // If the user did not click on another interactive item, return focus to the trigger\n if (!target.matches(INTERACTIVE_ELEMENTS_QUERY)) {\n triggerButton.focus();\n }\n }\n };\n\n // Any necessary side effects required on dropdown close\n const onCloseCleanupActions = () => {\n onClose?.();\n document.removeEventListener('keyup', keyUpListener);\n document.removeEventListener('click', clickOutsideListener);\n };\n\n // Add the main trigger button toggle functionality\n triggerButton.addEventListener('click', () => {\n if (\n document\n .getElementById(triggerElementId)\n ?.getAttribute('aria-expanded') === 'true'\n ) {\n closeDropdown({\n triggerElementId,\n dropdownContentId,\n onClose: onCloseCleanupActions,\n });\n } else {\n openDropdown({\n triggerElementId,\n dropdownContentId,\n });\n onOpen?.();\n\n document.addEventListener('keyup', keyUpListener);\n document.addEventListener('click', clickOutsideListener);\n }\n });\n\n if (dropdownContentCloseButtonId) {\n // The dropdown content has a 'close' button inside that we also need to handle\n document\n .getElementById(dropdownContentCloseButtonId)\n ?.addEventListener('click', () => {\n closeDropdown({\n triggerElementId,\n dropdownContentId,\n onClose: onCloseCleanupActions,\n });\n\n document.getElementById(triggerElementId)?.focus();\n });\n }\n\n return {\n closeDropdown: () => {\n closeDropdown({\n triggerElementId,\n dropdownContentId,\n onClose: onCloseCleanupActions,\n });\n },\n };\n};\n","import debounce from 'lodash.debounce';\n\n/**\n * A util function to wrap any action with lodash's `debounce` (https://lodash.com/docs/#debounce).\n * To use this util, wrap it in the util like so: debounceAction(onSearchBoxType.bind(this));\n *\n * By default, this util uses a default time of 300ms, and includes a default config of `{ leading: false }`.\n * These values can be overridden: debounceAction(this.onSearchBoxType.bind(this), { time: 100, config: { leading: true }});\n *\n *\n * @param {Function} action - The function that should be wrapped with `debounce`.\n * @param {Number} [time=300] - The number of milliseconds to wait.\n * @param {Object} [config={ leading: false }] - Any configuration for the debounce function.\n *\n * @returns {Function} A function wrapped in `debounce`.\n */\nexport function debounceAction(\n action,\n { time = 300, config = { leading: false } } = {},\n) {\n const configs = { ...config };\n return debounce(action, time, configs);\n}\n","import { useState, useEffect } from 'preact/hooks';\nimport PropTypes from 'prop-types';\n\n/**\n * Checker that return true if element is a form element\n *\n * @param {node} element to be checked\n *\n * @returns {boolean} isFormField\n */\nfunction isFormField(element) {\n if (element instanceof HTMLElement === false) return false;\n\n const name = element.nodeName.toLowerCase();\n const type = (element.getAttribute('type') || '').toLowerCase();\n return (\n name === 'select' ||\n name === 'textarea' ||\n (name === 'input' &&\n type !== 'submit' &&\n type !== 'reset' &&\n type !== 'checkbox' &&\n type !== 'radio') ||\n element.isContentEditable\n );\n}\n\n/**\n * Function to handle converting key presses to callback functions\n *\n * @param {KeyboardEvent} e Keyboard event\n * @param {String} keys special keys formatted in a string\n * @param {Array} chain array of past keys\n * @param {Object} shortcuts object containing callback functions\n *\n * @returns {Array} New chain\n */\nconst callShortcut = (e, keys, chain, shortcuts) => {\n const shortcut =\n chain && chain.length > 0\n ? shortcuts[`${chain.join('~')}~${e.code}`]\n : shortcuts[`${keys}${e.code}`] ||\n shortcuts[`${keys}${e.key.toLowerCase()}`];\n\n // if a valid shortcut is found call it and reset the chain\n if (shortcut) {\n shortcut(e);\n return [];\n }\n\n // if we have keys don't add to the chain\n if (keys || e.key === 'Shift') {\n return [];\n }\n\n return [...chain, e.code];\n};\n\n// Default options to be used if null\nconst defaultOptions = {\n timeout: 0, // The default is zero as we want no delays between keystrokes by default.\n};\n\n/**\n * hook that can be added to a component to listen\n * for keyboard presses\n *\n * @example\n * const shortcuts = {\n * 'ctrl+alt+KeyG': (e) => {\n * e.preventDefault();\n * alert('Control Alt G has been pressed');\n * },\n * 'KeyG~KeyH': (e) => {\n * e.preventDefault();\n * alert('G has been pressed quickly followed by H');\n * },\n * '?': (e) => {\n * setIsHelpVisible(true);\n * }\n * }\n *\n * useKeyboardShortcuts(shortcuts, someElementOrWindowObject, {timeout: 1500});\n *\n * @param {object} shortcuts List of keyboard shortcuts/event\n * @param {EventTarget} [eventTarget=window] An event target.\n * @param {object} [options = {}] An object for extra options\n *\n */\nexport function useKeyboardShortcuts(\n shortcuts,\n eventTarget = window,\n options = {},\n) {\n const [storedShortcuts] = useState(shortcuts);\n const [keyChain, setKeyChain] = useState([]);\n const [mergedOptions, setMergedOptions] = useState({\n ...defaultOptions,\n ...options,\n });\n\n // update mergedOptions if options prop changes\n useEffect(() => {\n const newOptions = {};\n if (typeof options.timeout === 'number')\n newOptions.timeout = options.timeout;\n setMergedOptions({ ...defaultOptions, ...newOptions });\n }, [options.timeout]);\n\n // clear key chain after timeout is reached\n useEffect(() => {\n if (keyChain.length <= 0) return;\n\n const timeout = window.setTimeout(() => {\n clearTimeout(timeout);\n setKeyChain([]);\n }, mergedOptions.timeout);\n\n return () => clearTimeout(timeout);\n }, [keyChain.length, mergedOptions.timeout]);\n\n // set up event listeners\n useEffect(() => {\n if (!storedShortcuts || Object.keys(storedShortcuts).length === 0) return;\n\n const keyEvent = (e) => {\n if (e.defaultPrevented) return;\n\n const ctrlKeyEntry = e.ctrlKey ? 'ctrl+' : '';\n const cmdKeyEntry = e.metaKey ? 'cmd+' : '';\n const altKeyEntry = e.altKey ? 'alt+' : '';\n const shiftKeyEntry = e.shiftKey ? 'shift+' : '';\n\n // We build the special keys string in an opinionated order to ensure consistency\n const keys = `${ctrlKeyEntry}${cmdKeyEntry}${altKeyEntry}${shiftKeyEntry}`;\n\n // If no special keys, except shift, are pressed and focus is inside a field return\n if (e.target instanceof Node && isFormField(e.target) && !keys) return;\n\n const newChain = callShortcut(e, keys, keyChain, storedShortcuts);\n\n // update keychain with latest chain\n setKeyChain(newChain);\n };\n\n eventTarget?.addEventListener('keydown', keyEvent);\n\n return () => eventTarget?.removeEventListener('keydown', keyEvent);\n }, [keyChain, storedShortcuts, eventTarget]);\n}\n\n/**\n * A component that can be added to a component to listen\n * for keyboard presses using the useKeyboardShortcuts hook\n *\n * @example\n * const shortcuts = {\n * 'ctrl+alt+KeyG': (e) => {\n * e.preventDefault();\n * alert('Control Alt G has been pressed')\n * }\n * }\n *\n * \n * \n *\n * @param {object} shortcuts List of keyboard shortcuts/event\n * @param {EventTarget} [eventTarget=window] An event target.\n * @param {object} [options = {}] An object for extra options\n *\n */\nexport function KeyboardShortcuts({ shortcuts, eventTarget, options }) {\n useKeyboardShortcuts(shortcuts, eventTarget, options);\n\n return null;\n}\n\nKeyboardShortcuts.propTypes = {\n shortcuts: PropTypes.object.isRequired,\n options: PropTypes.shape({\n timeout: PropTypes.number,\n }),\n eventTarget: PropTypes.oneOfType([\n PropTypes.instanceOf(Element),\n PropTypes.instanceOf(Window),\n ]),\n};\n\nKeyboardShortcuts.defaultProps = {\n shortcuts: {},\n options: {},\n eventTarget: window,\n};\n","// Unique ID applied to modals created using the showWindowModal function\nexport const WINDOW_MODAL_ID = 'window-modal';\n\n// We only import these modules if a user actually triggers a modal. Here we cache them so they are only imported once.\nlet preactImport;\nlet modalImports;\n\nconst getPreactImport = () => {\n if (!preactImport) {\n preactImport = import('preact');\n }\n return preactImport;\n};\n\nconst getModalImports = () => {\n if (!modalImports) {\n modalImports = [import('@crayons/Modal'), getPreactImport()];\n }\n return Promise.all(modalImports);\n};\n\n/**\n * This helper function presents content inside a Preact modal.\n *\n * The modal content may be passed either as:\n * - the actual HTML (using modalContent prop), which will be dropped straight into the modal\n * - a CSS selector (using contentSelector prop), which will be used to locate the HTML content on the current page before dropping it into the modal\n *\n * Only one modal will be presented at any given time. All additional props will be passed directly to the Modal component.\n *\n * @param {Object} args\n * @param {HTMLElement} args.modalContent The HTML to display inside of the modal\n * @param {string} args.contentSelector The CSS query to locate the HTML to be presented in the modal, as an alternative to passing the actual HTML (e.g. '#my-modal-content')\n * @param {Function} args.onOpen A callback function to run when the modal opens. This can be useful, for example, to attach any event listeners to items inside the modal.\n * @param {Object} args.document Allows us to specify which \"document\" is relevant; e.g. use within iframes.\n */\nexport const showWindowModal = async ({\n modalContent,\n contentSelector,\n onOpen,\n document = window.document,\n ...modalProps\n}) => {\n const [{ Modal }, { render, h }] = await getModalImports();\n\n // Guard against two modals being opened at once\n let currentModalContainer = document.getElementById(WINDOW_MODAL_ID);\n if (currentModalContainer) {\n render(null, currentModalContainer);\n } else {\n currentModalContainer = document.createElement('div');\n currentModalContainer.setAttribute('id', WINDOW_MODAL_ID);\n document.body.appendChild(currentModalContainer);\n }\n\n render(\n {\n render(null, currentModalContainer);\n }}\n focusTrapSelector={`#${WINDOW_MODAL_ID}`}\n document={document}\n {...modalProps}\n >\n \n ,\n currentModalContainer,\n );\n\n onOpen?.();\n};\n\n/**\n * This helper function closes any currently open window modal. This can be useful, for example, if your modal contains a \"cancel\" button.\n */\nexport const closeWindowModal = async (document = window.document) => {\n const currentModalContainer = document.getElementById(WINDOW_MODAL_ID);\n if (currentModalContainer) {\n const { render } = await getPreactImport();\n render(null, currentModalContainer);\n }\n};\n","import { addSnackbarItem } from '../Snackbar';\n\n/**\n * @file Manages logic to validate file uploads client-side. In general, the\n * validations work by looping over input form fields with a type of file and\n * checking the size and format of the files upload by the user.\n */\n\n/**\n * An object containing the top level MIME type as the key and the max file\n * size in MB for the value. To use a different value than these defaults,\n * simply add a data-max-file-mb attribute to the input form field with the\n * max file size in MB. If that attribute is found, it takes priority over these\n * defaults.\n *\n * @constant {Object.}\n */\nconst MAX_FILE_SIZE_MB = Object.freeze({\n image: 25,\n video: 50,\n});\n\n/**\n * Permitted file types using the top level MIME type (i.e. image for\n * image/png). To specify permitted file types, simply add a\n * data-permitted-file-types attribute to the input form field as an Array of\n * strings specifying the top level MIME types that are permitted.\n *\n * @constant {string[]}\n */\nconst PERMITTED_FILE_TYPES = ['image'];\n\n/**\n * The maximum length of the file name to prevent errors on the backend when a\n * file name is too long.\n *\n * @constant {number}\n */\nconst MAX_FILE_NAME_LENGTH = 250;\n\n/**\n * Adds error messages in the form of a div with red text.\n *\n * @param {string} msg - The error message to be displayed to the user\n *\n * @returns {HTMLElement} The error element that was added to the DOM\n */\nfunction addErrorMessage(msg) {\n if (top.addSnackbarItem) {\n // The Comment editor's context (MarkdownToolbar component) doesn't have\n // access to the Snackbar element in the DOM, so it needs to use `top`\n top.addSnackbarItem({\n message: msg,\n addCloseButton: true,\n });\n } else {\n // The Post editor (Toolbar component) doesn't have access to\n // `top.addSnackbarItem` so we need to check to ensure if it's undefined\n addSnackbarItem({\n message: msg,\n addCloseButton: true,\n });\n }\n}\n\n/**\n * Handles errors for files that are too large.\n *\n * @param {object} fileSizeErrorHandler - A custom function to be ran after the default error handling\n * @param {number} fileSizeMb - The size of the file in MB\n * @param {?number} maxFileSizeMb - The max file size limit in MB\n */\nfunction handleFileSizeError(fileSizeErrorHandler, fileSizeMb, maxFileSizeMb) {\n if (fileSizeErrorHandler) {\n fileSizeErrorHandler();\n } else {\n let errorMessage = `File size too large (${fileSizeMb} MB).`;\n\n // If a user uploads a file type that we haven't defined a max size limit for then maxFileSizeMb\n // could be NaN\n if (maxFileSizeMb >= 0) {\n errorMessage += ` The limit is ${maxFileSizeMb} MB.`;\n }\n\n addErrorMessage(errorMessage);\n }\n}\n\n/**\n * Handles errors for files that are not a valid format.\n *\n * @param {object} fileSizeErrorHandler - A custom function to be ran after the default error handling\n * @param {string} fileType - The top level file type (i.e. image for image/png)\n * @param {string[]} permittedFileTypes - The top level file types (i.e. image for image/png) that are permitted\n */\nfunction handleFileTypeError(\n fileTypeErrorHandler,\n fileType,\n permittedFileTypes,\n) {\n if (fileTypeErrorHandler) {\n fileTypeErrorHandler();\n } else {\n const fileTypeBracketed =\n fileType && fileType.length !== 0 ? ` (${fileType})` : '';\n const errorMessage = `Invalid file format${fileTypeBracketed}. Only ${permittedFileTypes.join(\n ', ',\n )} files are permitted.`;\n addErrorMessage(errorMessage);\n }\n}\n\n/**\n * Handles errors for files with names that are too long.\n *\n * @param {object} fileNameLengthErrorHandler - A custom function to be ran after the default error handling\n * @param {number} maxFileNameLength - The max number of characters permitted for a file name\n */\nfunction handleFileNameLengthError(\n fileNameLengthErrorHandler,\n maxFileNameLength,\n) {\n if (fileNameLengthErrorHandler) {\n fileNameLengthErrorHandler();\n } else {\n const errorMessage = `File name is too long. It can't be longer than ${maxFileNameLength} characters.`;\n addErrorMessage(errorMessage);\n }\n}\n\n/**\n * Validates the file size and handles the error if it's invalid.\n *\n * @external File\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/File File}\n *\n * @param {File} file - The file attached by the user\n * @param {string} fileType - The top level file type (i.e. image for image/png)\n * @param {HTMLElement} fileInput - An input form field with type of file\n *\n * @returns {Boolean} Returns false if the file is too big. Otherwise, returns true.\n */\nfunction validateFileSize(file, fileType, fileInput) {\n let { maxFileSizeMb } = fileInput.dataset;\n\n const { fileSizeErrorHandler } = fileInput.dataset;\n\n const fileSizeMb = (file.size / (1024 * 1024)).toFixed(2);\n maxFileSizeMb = Number(maxFileSizeMb || MAX_FILE_SIZE_MB[fileType]);\n\n const isValidFileSize = fileSizeMb <= maxFileSizeMb;\n\n if (!isValidFileSize) {\n handleFileSizeError(fileSizeErrorHandler, fileSizeMb, maxFileSizeMb);\n }\n\n return isValidFileSize;\n}\n\n/**\n * Validates the file type and handles the error if it's invalid.\n *\n * @external File\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/File File}\n *\n * @param {File} file - The file attached by the user\n * @param {string} fileType - The top level file type (i.e. image for image/png)\n * @param {HTMLElement} fileInput - An input form field with type of file\n *\n * @returns {Boolean} Returns false if the files is an invalid format. Otherwise, returns true.\n */\nfunction validateFileType(file, fileType, fileInput) {\n let { permittedFileTypes } = fileInput.dataset;\n\n if (permittedFileTypes) {\n permittedFileTypes = JSON.parse(permittedFileTypes);\n }\n\n permittedFileTypes = permittedFileTypes || PERMITTED_FILE_TYPES;\n\n const { fileTypeErrorHandler } = fileInput.dataset;\n\n const isValidFileType = permittedFileTypes.includes(fileType);\n\n if (!isValidFileType) {\n handleFileTypeError(fileTypeErrorHandler, fileType, permittedFileTypes);\n }\n\n return isValidFileType;\n}\n\n/**\n * Validates the length of the file name and handles the error if it's invalid.\n *\n * @external File\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/File File}\n *\n * @param {File} file - The file attached by the user\n * @param {HTMLElement} fileInput - An input form field with type of file\n *\n * @returns {Boolean} Returns false if the file name is too long. Otherwise, returns true.\n */\nfunction validateFileNameLength(file, fileInput) {\n let { maxFileNameLength } = fileInput.dataset;\n\n maxFileNameLength = Number(maxFileNameLength || MAX_FILE_NAME_LENGTH);\n\n const { fileNameLengthErrorHandler } = fileInput.dataset;\n\n const isValidFileNameLength = file.name.length <= maxFileNameLength;\n\n if (!isValidFileNameLength) {\n handleFileNameLengthError(fileNameLengthErrorHandler, maxFileNameLength);\n }\n\n return isValidFileNameLength;\n}\n\n/**\n * This is the core function to handle validations of uploaded files. It loops\n * through all the uploaded files for the given fileInput and checks the file\n * size, file format, and file name length. If a file fails a validation, the\n * error is handled.\n *\n * @param {HTMLElement} fileInput - An input form field with type of file\n *\n * @returns {Boolean} Returns false if any files failed validations. Otherwise, returns true.\n */\nfunction validateFileInput(fileInput) {\n let isValidFileInput = true;\n\n const files = Array.from(fileInput.files);\n\n for (let i = 0; i < files.length; i += 1) {\n const file = files[i];\n const fileType = file.type.split('/')[0];\n\n const isValidFileSize = validateFileSize(file, fileType, fileInput);\n\n if (!isValidFileSize) {\n isValidFileInput = false;\n break;\n }\n\n const isValidFileType = validateFileType(file, fileType, fileInput);\n\n if (!isValidFileType) {\n isValidFileInput = false;\n break;\n }\n\n const isValidFileNameLength = validateFileNameLength(file, fileInput);\n\n if (!isValidFileNameLength) {\n isValidFileInput = false;\n break;\n }\n }\n\n return isValidFileInput;\n}\n\n/**\n * This function is designed to be exported in areas where we are doing more\n * custom implementations of file uploading using Preact. It can then be used\n * in Preact event handlers. It loops through all file input fields on the DOM\n * and validates any attached files.\n *\n * @returns {Boolean} Returns false if any files failed validations. Otherwise, returns true.\n */\nexport function validateFileInputs() {\n let validFileInputs = true;\n const fileInputs = document.querySelectorAll('input[type=\"file\"]');\n\n for (let i = 0; i < fileInputs.length; i += 1) {\n const fileInput = fileInputs[i];\n const validFileInput = validateFileInput(fileInput);\n\n if (!validFileInput) {\n validFileInputs = false;\n break;\n }\n }\n\n return validFileInputs;\n}\n\n// This is written so that it works automagically by just including this pack\n// in a view.\nconst fileInputs = document.querySelectorAll('input[type=\"file\"]');\n\nfileInputs.forEach((fileInput) => {\n fileInput.addEventListener('change', () => {\n validateFileInput(fileInput);\n });\n});\n","/*!\n * Ahoy.js v0.4.1\n * Simple, powerful JavaScript analytics\n * https://github.com/ankane/ahoy.js\n * MIT License\n */\n\n// https://www.quirksmode.org/js/cookies.html\n\nvar Cookies = {\n set: function (name, value, ttl, domain) {\n var expires = \"\";\n var cookieDomain = \"\";\n if (ttl) {\n var date = new Date();\n date.setTime(date.getTime() + (ttl * 60 * 1000));\n expires = \"; expires=\" + date.toGMTString();\n }\n if (domain) {\n cookieDomain = \"; domain=\" + domain;\n }\n document.cookie = name + \"=\" + escape(value) + expires + cookieDomain + \"; path=/; samesite=lax\";\n },\n get: function (name) {\n var i, c;\n var nameEQ = name + \"=\";\n var ca = document.cookie.split(';');\n for (i = 0; i < ca.length; i++) {\n c = ca[i];\n while (c.charAt(0) === ' ') {\n c = c.substring(1, c.length);\n }\n if (c.indexOf(nameEQ) === 0) {\n return unescape(c.substring(nameEQ.length, c.length));\n }\n }\n return null;\n }\n};\n\nvar config = {\n urlPrefix: \"\",\n visitsUrl: \"/ahoy/visits\",\n eventsUrl: \"/ahoy/events\",\n page: null,\n platform: \"Web\",\n useBeacon: true,\n startOnReady: true,\n trackVisits: true,\n cookies: true,\n cookieDomain: null,\n headers: {},\n visitParams: {},\n withCredentials: false,\n visitDuration: 4 * 60, // default 4 hours\n visitorDuration: 2 * 365 * 24 * 60 // default 2 years\n};\n\nvar ahoy = window.ahoy || window.Ahoy || {};\n\nahoy.configure = function (options) {\n for (var key in options) {\n if (Object.prototype.hasOwnProperty.call(options, key)) {\n config[key] = options[key];\n }\n }\n};\n\n// legacy\nahoy.configure(ahoy);\n\nvar $ = window.jQuery || window.Zepto || window.$;\nvar visitId, visitorId, track;\nvar isReady = false;\nvar queue = [];\nvar canStringify = typeof(JSON) !== \"undefined\" && typeof(JSON.stringify) !== \"undefined\";\nvar eventQueue = [];\n\nfunction visitsUrl() {\n return config.urlPrefix + config.visitsUrl;\n}\n\nfunction eventsUrl() {\n return config.urlPrefix + config.eventsUrl;\n}\n\nfunction isEmpty(obj) {\n return Object.keys(obj).length === 0;\n}\n\nfunction canTrackNow() {\n return (config.useBeacon || config.trackNow) && isEmpty(config.headers) && canStringify && typeof(window.navigator.sendBeacon) !== \"undefined\" && !config.withCredentials;\n}\n\nfunction serialize(object) {\n var data = new FormData();\n for (var key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n data.append(key, object[key]);\n }\n }\n return data;\n}\n\n// cookies\n\nfunction setCookie(name, value, ttl) {\n Cookies.set(name, value, ttl, config.cookieDomain || config.domain);\n}\n\nfunction getCookie(name) {\n return Cookies.get(name);\n}\n\nfunction destroyCookie(name) {\n Cookies.set(name, \"\", -1);\n}\n\nfunction log(message) {\n if (getCookie(\"ahoy_debug\")) {\n window.console.log(message);\n }\n}\n\nfunction setReady() {\n var callback;\n while ((callback = queue.shift())) {\n callback();\n }\n isReady = true;\n}\n\nahoy.ready = function (callback) {\n if (isReady) {\n callback();\n } else {\n queue.push(callback);\n }\n};\n\nfunction matchesSelector(element, selector) {\n var matches = element.matches ||\n element.matchesSelector ||\n element.mozMatchesSelector ||\n element.msMatchesSelector ||\n element.oMatchesSelector ||\n element.webkitMatchesSelector;\n\n if (matches) {\n if (matches.apply(element, [selector])) {\n return element;\n } else if (element.parentElement) {\n return matchesSelector(element.parentElement, selector);\n }\n return null;\n } else {\n log(\"Unable to match\");\n return null;\n }\n}\n\nfunction onEvent(eventName, selector, callback) {\n document.addEventListener(eventName, function (e) {\n var matchedElement = matchesSelector(e.target, selector);\n if (matchedElement) {\n var skip = getClosest(matchedElement, \"data-ahoy-skip\");\n if (skip !== null && skip !== \"false\") { return; }\n\n callback.call(matchedElement, e);\n }\n });\n}\n\n// http://beeker.io/jquery-document-ready-equivalent-vanilla-javascript\nfunction documentReady(callback) {\n if (document.readyState === \"interactive\" || document.readyState === \"complete\") {\n setTimeout(callback, 0);\n } else {\n document.addEventListener(\"DOMContentLoaded\", callback);\n }\n}\n\n// https://stackoverflow.com/a/2117523/1177228\nfunction generateId() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0;\n var v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\nfunction saveEventQueue() {\n if (config.cookies && canStringify) {\n setCookie(\"ahoy_events\", JSON.stringify(eventQueue), 1);\n }\n}\n\n// from rails-ujs\n\nfunction csrfToken() {\n var meta = document.querySelector(\"meta[name=csrf-token]\");\n return meta && meta.content;\n}\n\nfunction csrfParam() {\n var meta = document.querySelector(\"meta[name=csrf-param]\");\n return meta && meta.content;\n}\n\nfunction CSRFProtection(xhr) {\n var token = csrfToken();\n if (token) { xhr.setRequestHeader(\"X-CSRF-Token\", token); }\n}\n\nfunction sendRequest(url, data, success) {\n if (canStringify) {\n if ($ && $.ajax) {\n $.ajax({\n type: \"POST\",\n url: url,\n data: JSON.stringify(data),\n contentType: \"application/json; charset=utf-8\",\n dataType: \"json\",\n beforeSend: CSRFProtection,\n success: success,\n headers: config.headers,\n xhrFields: {\n withCredentials: config.withCredentials\n }\n });\n } else {\n var xhr = new XMLHttpRequest();\n xhr.open(\"POST\", url, true);\n xhr.withCredentials = config.withCredentials;\n xhr.setRequestHeader(\"Content-Type\", \"application/json\");\n for (var header in config.headers) {\n if (Object.prototype.hasOwnProperty.call(config.headers, header)) {\n xhr.setRequestHeader(header, config.headers[header]);\n }\n }\n xhr.onload = function () {\n if (xhr.status === 200) {\n success();\n }\n };\n CSRFProtection(xhr);\n xhr.send(JSON.stringify(data));\n }\n }\n}\n\nfunction eventData(event) {\n var data = {\n events: [event]\n };\n if (config.cookies) {\n data.visit_token = event.visit_token;\n data.visitor_token = event.visitor_token;\n }\n delete event.visit_token;\n delete event.visitor_token;\n return data;\n}\n\nfunction trackEvent(event) {\n ahoy.ready(function () {\n sendRequest(eventsUrl(), eventData(event), function () {\n // remove from queue\n for (var i = 0; i < eventQueue.length; i++) {\n if (eventQueue[i].id === event.id) {\n eventQueue.splice(i, 1);\n break;\n }\n }\n saveEventQueue();\n });\n });\n}\n\nfunction trackEventNow(event) {\n ahoy.ready(function () {\n var data = eventData(event);\n var param = csrfParam();\n var token = csrfToken();\n if (param && token) { data[param] = token; }\n // stringify so we keep the type\n data.events_json = JSON.stringify(data.events);\n delete data.events;\n window.navigator.sendBeacon(eventsUrl(), serialize(data));\n });\n}\n\nfunction page() {\n return config.page || window.location.pathname;\n}\n\nfunction presence(str) {\n return (str && str.length > 0) ? str : null;\n}\n\nfunction cleanObject(obj) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n if (obj[key] === null) {\n delete obj[key];\n }\n }\n }\n return obj;\n}\n\nfunction eventProperties() {\n return cleanObject({\n tag: this.tagName.toLowerCase(),\n id: presence(this.id),\n \"class\": presence(this.className),\n page: page(),\n section: getClosest(this, \"data-section\")\n });\n}\n\nfunction getClosest(element, attribute) {\n for (; element && element !== document; element = element.parentNode) {\n if (element.hasAttribute(attribute)) {\n return element.getAttribute(attribute);\n }\n }\n\n return null;\n}\n\nfunction createVisit() {\n isReady = false;\n\n visitId = ahoy.getVisitId();\n visitorId = ahoy.getVisitorId();\n track = getCookie(\"ahoy_track\");\n\n if (config.cookies === false || config.trackVisits === false) {\n log(\"Visit tracking disabled\");\n setReady();\n } else if (visitId && visitorId && !track) {\n // TODO keep visit alive?\n log(\"Active visit\");\n setReady();\n } else {\n if (!visitId) {\n visitId = generateId();\n setCookie(\"ahoy_visit\", visitId, config.visitDuration);\n }\n\n // make sure cookies are enabled\n if (getCookie(\"ahoy_visit\")) {\n log(\"Visit started\");\n\n if (!visitorId) {\n visitorId = generateId();\n setCookie(\"ahoy_visitor\", visitorId, config.visitorDuration);\n }\n\n var data = {\n visit_token: visitId,\n visitor_token: visitorId,\n platform: config.platform,\n landing_page: window.location.href,\n screen_width: window.screen.width,\n screen_height: window.screen.height,\n js: true\n };\n\n // referrer\n if (document.referrer.length > 0) {\n data.referrer = document.referrer;\n }\n\n for (var key in config.visitParams) {\n if (Object.prototype.hasOwnProperty.call(config.visitParam, key)) {\n data[key] = config.visitParams[key];\n }\n }\n\n log(data);\n\n sendRequest(visitsUrl(), data, function () {\n // wait until successful to destroy\n destroyCookie(\"ahoy_track\");\n setReady();\n });\n } else {\n log(\"Cookies disabled\");\n setReady();\n }\n }\n}\n\nahoy.getVisitId = ahoy.getVisitToken = function () {\n return getCookie(\"ahoy_visit\");\n};\n\nahoy.getVisitorId = ahoy.getVisitorToken = function () {\n return getCookie(\"ahoy_visitor\");\n};\n\nahoy.reset = function () {\n destroyCookie(\"ahoy_visit\");\n destroyCookie(\"ahoy_visitor\");\n destroyCookie(\"ahoy_events\");\n destroyCookie(\"ahoy_track\");\n return true;\n};\n\nahoy.debug = function (enabled) {\n if (enabled === false) {\n destroyCookie(\"ahoy_debug\");\n } else {\n setCookie(\"ahoy_debug\", \"t\", 365 * 24 * 60); // 1 year\n }\n return true;\n};\n\nahoy.track = function (name, properties) {\n // generate unique id\n var event = {\n name: name,\n properties: properties || {},\n time: (new Date()).getTime() / 1000.0,\n id: generateId(),\n js: true\n };\n\n ahoy.ready(function () {\n if (config.cookies && !ahoy.getVisitId()) {\n createVisit();\n }\n\n ahoy.ready(function () {\n log(event);\n\n event.visit_token = ahoy.getVisitId();\n event.visitor_token = ahoy.getVisitorId();\n\n if (canTrackNow()) {\n trackEventNow(event);\n } else {\n eventQueue.push(event);\n saveEventQueue();\n\n // wait in case navigating to reduce duplicate events\n setTimeout(function () {\n trackEvent(event);\n }, 1000);\n }\n });\n });\n\n return true;\n};\n\nahoy.trackView = function (additionalProperties) {\n var properties = {\n url: window.location.href,\n title: document.title,\n page: page()\n };\n\n if (additionalProperties) {\n for (var propName in additionalProperties) {\n if (Object.prototype.hasOwnProperty.call(additionalProperties, propName)) {\n properties[propName] = additionalProperties[propName];\n }\n }\n }\n ahoy.track(\"$view\", properties);\n};\n\nahoy.trackClicks = function (selector) {\n if (selector === undefined) {\n throw new Error(\"Missing selector\");\n }\n onEvent(\"click\", selector, function (e) {\n var properties = eventProperties.call(this, e);\n properties.text = properties.tag === \"input\" ? this.value : (this.textContent || this.innerText || this.innerHTML).replace(/[\\s\\r\\n]+/g, \" \").trim();\n properties.href = this.href;\n ahoy.track(\"$click\", properties);\n });\n};\n\nahoy.trackSubmits = function (selector) {\n if (selector === undefined) {\n throw new Error(\"Missing selector\");\n }\n onEvent(\"submit\", selector, function (e) {\n var properties = eventProperties.call(this, e);\n ahoy.track(\"$submit\", properties);\n });\n};\n\nahoy.trackChanges = function (selector) {\n log(\"trackChanges is deprecated and will be removed in 0.5.0\");\n if (selector === undefined) {\n throw new Error(\"Missing selector\");\n }\n onEvent(\"change\", selector, function (e) {\n var properties = eventProperties.call(this, e);\n ahoy.track(\"$change\", properties);\n });\n};\n\n// push events from queue\ntry {\n eventQueue = JSON.parse(getCookie(\"ahoy_events\") || \"[]\");\n} catch (e) {\n // do nothing\n}\n\nfor (var i = 0; i < eventQueue.length; i++) {\n trackEvent(eventQueue[i]);\n}\n\nahoy.start = function () {\n createVisit();\n\n ahoy.start = function () {};\n};\n\ndocumentReady(function () {\n if (config.startOnReady) {\n ahoy.start();\n }\n});\n\nexport { ahoy as default };\n","export function getCsrfToken() {\n const element = document.querySelector(`meta[name='csrf-token']`);\n\n return element !== null ? element.content : undefined;\n}\n\nconst getWaitOnUserDataHandler = ({ resolve, reject, waitTime = 20 }) => {\n let totalTimeWaiting = 0;\n\n return function waitingOnUserData() {\n if (totalTimeWaiting === 3000) {\n reject(new Error(\"Couldn't find user data on page.\"));\n return;\n }\n\n const csrfToken = getCsrfToken(document);\n const { user } = document.body.dataset;\n\n if (user && csrfToken !== undefined) {\n const currentUser = JSON.parse(user);\n\n resolve({ currentUser, csrfToken });\n return;\n }\n\n totalTimeWaiting += waitTime;\n setTimeout(waitingOnUserData, waitTime);\n };\n};\n\nexport function getUserDataAndCsrfToken() {\n return new Promise((resolve, reject) => {\n getWaitOnUserDataHandler({ resolve, reject })();\n });\n}\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { defaultChildrenPropTypes } from '../common-prop-types';\nimport { Button } from '@crayons';\n\nexport const snackbarItemProps = {\n children: defaultChildrenPropTypes.isRequired,\n actions: PropTypes.arrayOf(\n PropTypes.shape({\n message: PropTypes.string.isRequired,\n handler: PropTypes.func.isRequired,\n lifespan: PropTypes.number.isRequired,\n }),\n ),\n};\n\nexport const SnackbarItem = ({ message, actions = [] }) => (\n
\n
\n {message}\n
\n
\n {actions.map(({ text, handler }) => (\n \n ))}\n
\n
\n);\n\nSnackbarItem.displayName = 'SnackbarItem';\n\nSnackbarItem.propTypes = snackbarItemProps.isRequired;\n","var map = {\n\t\"./af\": 45,\n\t\"./af.js\": 45,\n\t\"./ar\": 46,\n\t\"./ar-dz\": 47,\n\t\"./ar-dz.js\": 47,\n\t\"./ar-kw\": 48,\n\t\"./ar-kw.js\": 48,\n\t\"./ar-ly\": 49,\n\t\"./ar-ly.js\": 49,\n\t\"./ar-ma\": 50,\n\t\"./ar-ma.js\": 50,\n\t\"./ar-sa\": 51,\n\t\"./ar-sa.js\": 51,\n\t\"./ar-tn\": 52,\n\t\"./ar-tn.js\": 52,\n\t\"./ar.js\": 46,\n\t\"./az\": 53,\n\t\"./az.js\": 53,\n\t\"./be\": 54,\n\t\"./be.js\": 54,\n\t\"./bg\": 55,\n\t\"./bg.js\": 55,\n\t\"./bm\": 56,\n\t\"./bm.js\": 56,\n\t\"./bn\": 57,\n\t\"./bn-bd\": 58,\n\t\"./bn-bd.js\": 58,\n\t\"./bn.js\": 57,\n\t\"./bo\": 59,\n\t\"./bo.js\": 59,\n\t\"./br\": 60,\n\t\"./br.js\": 60,\n\t\"./bs\": 61,\n\t\"./bs.js\": 61,\n\t\"./ca\": 62,\n\t\"./ca.js\": 62,\n\t\"./cs\": 63,\n\t\"./cs.js\": 63,\n\t\"./cv\": 64,\n\t\"./cv.js\": 64,\n\t\"./cy\": 65,\n\t\"./cy.js\": 65,\n\t\"./da\": 66,\n\t\"./da.js\": 66,\n\t\"./de\": 67,\n\t\"./de-at\": 68,\n\t\"./de-at.js\": 68,\n\t\"./de-ch\": 69,\n\t\"./de-ch.js\": 69,\n\t\"./de.js\": 67,\n\t\"./dv\": 70,\n\t\"./dv.js\": 70,\n\t\"./el\": 71,\n\t\"./el.js\": 71,\n\t\"./en-au\": 72,\n\t\"./en-au.js\": 72,\n\t\"./en-ca\": 73,\n\t\"./en-ca.js\": 73,\n\t\"./en-gb\": 74,\n\t\"./en-gb.js\": 74,\n\t\"./en-ie\": 75,\n\t\"./en-ie.js\": 75,\n\t\"./en-il\": 76,\n\t\"./en-il.js\": 76,\n\t\"./en-in\": 77,\n\t\"./en-in.js\": 77,\n\t\"./en-nz\": 78,\n\t\"./en-nz.js\": 78,\n\t\"./en-sg\": 79,\n\t\"./en-sg.js\": 79,\n\t\"./eo\": 80,\n\t\"./eo.js\": 80,\n\t\"./es\": 81,\n\t\"./es-do\": 82,\n\t\"./es-do.js\": 82,\n\t\"./es-mx\": 83,\n\t\"./es-mx.js\": 83,\n\t\"./es-us\": 84,\n\t\"./es-us.js\": 84,\n\t\"./es.js\": 81,\n\t\"./et\": 85,\n\t\"./et.js\": 85,\n\t\"./eu\": 86,\n\t\"./eu.js\": 86,\n\t\"./fa\": 87,\n\t\"./fa.js\": 87,\n\t\"./fi\": 88,\n\t\"./fi.js\": 88,\n\t\"./fil\": 89,\n\t\"./fil.js\": 89,\n\t\"./fo\": 90,\n\t\"./fo.js\": 90,\n\t\"./fr\": 91,\n\t\"./fr-ca\": 92,\n\t\"./fr-ca.js\": 92,\n\t\"./fr-ch\": 93,\n\t\"./fr-ch.js\": 93,\n\t\"./fr.js\": 91,\n\t\"./fy\": 94,\n\t\"./fy.js\": 94,\n\t\"./ga\": 95,\n\t\"./ga.js\": 95,\n\t\"./gd\": 96,\n\t\"./gd.js\": 96,\n\t\"./gl\": 97,\n\t\"./gl.js\": 97,\n\t\"./gom-deva\": 98,\n\t\"./gom-deva.js\": 98,\n\t\"./gom-latn\": 99,\n\t\"./gom-latn.js\": 99,\n\t\"./gu\": 100,\n\t\"./gu.js\": 100,\n\t\"./he\": 101,\n\t\"./he.js\": 101,\n\t\"./hi\": 102,\n\t\"./hi.js\": 102,\n\t\"./hr\": 103,\n\t\"./hr.js\": 103,\n\t\"./hu\": 104,\n\t\"./hu.js\": 104,\n\t\"./hy-am\": 105,\n\t\"./hy-am.js\": 105,\n\t\"./id\": 106,\n\t\"./id.js\": 106,\n\t\"./is\": 107,\n\t\"./is.js\": 107,\n\t\"./it\": 108,\n\t\"./it-ch\": 109,\n\t\"./it-ch.js\": 109,\n\t\"./it.js\": 108,\n\t\"./ja\": 110,\n\t\"./ja.js\": 110,\n\t\"./jv\": 111,\n\t\"./jv.js\": 111,\n\t\"./ka\": 112,\n\t\"./ka.js\": 112,\n\t\"./kk\": 113,\n\t\"./kk.js\": 113,\n\t\"./km\": 114,\n\t\"./km.js\": 114,\n\t\"./kn\": 115,\n\t\"./kn.js\": 115,\n\t\"./ko\": 116,\n\t\"./ko.js\": 116,\n\t\"./ku\": 117,\n\t\"./ku.js\": 117,\n\t\"./ky\": 118,\n\t\"./ky.js\": 118,\n\t\"./lb\": 119,\n\t\"./lb.js\": 119,\n\t\"./lo\": 120,\n\t\"./lo.js\": 120,\n\t\"./lt\": 121,\n\t\"./lt.js\": 121,\n\t\"./lv\": 122,\n\t\"./lv.js\": 122,\n\t\"./me\": 123,\n\t\"./me.js\": 123,\n\t\"./mi\": 124,\n\t\"./mi.js\": 124,\n\t\"./mk\": 125,\n\t\"./mk.js\": 125,\n\t\"./ml\": 126,\n\t\"./ml.js\": 126,\n\t\"./mn\": 127,\n\t\"./mn.js\": 127,\n\t\"./mr\": 128,\n\t\"./mr.js\": 128,\n\t\"./ms\": 129,\n\t\"./ms-my\": 130,\n\t\"./ms-my.js\": 130,\n\t\"./ms.js\": 129,\n\t\"./mt\": 131,\n\t\"./mt.js\": 131,\n\t\"./my\": 132,\n\t\"./my.js\": 132,\n\t\"./nb\": 133,\n\t\"./nb.js\": 133,\n\t\"./ne\": 134,\n\t\"./ne.js\": 134,\n\t\"./nl\": 135,\n\t\"./nl-be\": 136,\n\t\"./nl-be.js\": 136,\n\t\"./nl.js\": 135,\n\t\"./nn\": 137,\n\t\"./nn.js\": 137,\n\t\"./oc-lnc\": 138,\n\t\"./oc-lnc.js\": 138,\n\t\"./pa-in\": 139,\n\t\"./pa-in.js\": 139,\n\t\"./pl\": 140,\n\t\"./pl.js\": 140,\n\t\"./pt\": 141,\n\t\"./pt-br\": 142,\n\t\"./pt-br.js\": 142,\n\t\"./pt.js\": 141,\n\t\"./ro\": 143,\n\t\"./ro.js\": 143,\n\t\"./ru\": 144,\n\t\"./ru.js\": 144,\n\t\"./sd\": 145,\n\t\"./sd.js\": 145,\n\t\"./se\": 146,\n\t\"./se.js\": 146,\n\t\"./si\": 147,\n\t\"./si.js\": 147,\n\t\"./sk\": 148,\n\t\"./sk.js\": 148,\n\t\"./sl\": 149,\n\t\"./sl.js\": 149,\n\t\"./sq\": 150,\n\t\"./sq.js\": 150,\n\t\"./sr\": 151,\n\t\"./sr-cyrl\": 152,\n\t\"./sr-cyrl.js\": 152,\n\t\"./sr.js\": 151,\n\t\"./ss\": 153,\n\t\"./ss.js\": 153,\n\t\"./sv\": 154,\n\t\"./sv.js\": 154,\n\t\"./sw\": 155,\n\t\"./sw.js\": 155,\n\t\"./ta\": 156,\n\t\"./ta.js\": 156,\n\t\"./te\": 157,\n\t\"./te.js\": 157,\n\t\"./tet\": 158,\n\t\"./tet.js\": 158,\n\t\"./tg\": 159,\n\t\"./tg.js\": 159,\n\t\"./th\": 160,\n\t\"./th.js\": 160,\n\t\"./tk\": 161,\n\t\"./tk.js\": 161,\n\t\"./tl-ph\": 162,\n\t\"./tl-ph.js\": 162,\n\t\"./tlh\": 163,\n\t\"./tlh.js\": 163,\n\t\"./tr\": 164,\n\t\"./tr.js\": 164,\n\t\"./tzl\": 165,\n\t\"./tzl.js\": 165,\n\t\"./tzm\": 166,\n\t\"./tzm-latn\": 167,\n\t\"./tzm-latn.js\": 167,\n\t\"./tzm.js\": 166,\n\t\"./ug-cn\": 168,\n\t\"./ug-cn.js\": 168,\n\t\"./uk\": 169,\n\t\"./uk.js\": 169,\n\t\"./ur\": 170,\n\t\"./ur.js\": 170,\n\t\"./uz\": 171,\n\t\"./uz-latn\": 172,\n\t\"./uz-latn.js\": 172,\n\t\"./uz.js\": 171,\n\t\"./vi\": 173,\n\t\"./vi.js\": 173,\n\t\"./x-pseudo\": 174,\n\t\"./x-pseudo.js\": 174,\n\t\"./yo\": 175,\n\t\"./yo.js\": 175,\n\t\"./zh-cn\": 176,\n\t\"./zh-cn.js\": 176,\n\t\"./zh-hk\": 177,\n\t\"./zh-hk.js\": 177,\n\t\"./zh-mo\": 178,\n\t\"./zh-mo.js\": 178,\n\t\"./zh-tw\": 179,\n\t\"./zh-tw.js\": 179\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn map[req];\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 216;","import PropTypes from 'prop-types';\nimport { h, Fragment } from 'preact';\nimport { useLayoutEffect, useRef, useCallback } from 'preact/hooks';\nimport { createFocusTrap } from 'focus-trap';\nimport { defaultChildrenPropTypes } from '../../common-prop-types';\nimport { KeyboardShortcuts } from './useKeyboardShortcuts';\n\n/**\n * Wrapper component to create a focus trap within the HTML element found by the given selector\n *\n * @example\n * import { FocusTrap } from \"shared/components/FocusTrap\";\n *\n * const ExampleComponent = ({ onClose }) => (\n * \n *
\n * \n *
\n *
\n * )\n *\n * @param {string} selector The CSS selector for the element where focus is to be trapped\n * @param {Array} children Child element(s) passed via composition\n * @param {Function} onDeactivate Callback function to be called when the focus trap is deactivated by navigation or Escape press\n * @param {boolean} clickOutsideDeactivates If true, the focus trap will deactivate when a user clicks outside of the trap area\n */\nexport const FocusTrap = ({\n selector,\n children,\n onDeactivate,\n clickOutsideDeactivates = false,\n document = window.document,\n}) => {\n const focusTrap = useRef(null);\n const deactivate = useCallback(() => onDeactivate(), [onDeactivate]);\n\n useLayoutEffect(() => {\n const currentLocationHref = document.location.href;\n const routeChangeObserver = new MutationObserver((mutations) => {\n const hasRouteChanged = mutations.some(\n () => currentLocationHref !== document.location.href,\n );\n\n // Ensure trap deactivates if user navigates from the page\n if (hasRouteChanged) {\n focusTrap.current?.deactivate();\n routeChangeObserver.disconnect();\n }\n });\n\n focusTrap.current = createFocusTrap(selector, {\n escapeDeactivates: false,\n clickOutsideDeactivates,\n onDeactivate: deactivate,\n document,\n });\n\n focusTrap.current.activate();\n routeChangeObserver.observe(document.querySelector('body'), {\n childList: true,\n });\n\n return () => {\n focusTrap.current.deactivate();\n routeChangeObserver.disconnect();\n };\n }, [clickOutsideDeactivates, selector, deactivate, document]);\n\n const shortcuts = {\n escape: onDeactivate,\n };\n\n return (\n \n {children}\n \n \n );\n};\n\nFocusTrap.defaultProps = {\n selector: '.crayons-modal',\n onDeactivate: () => {},\n};\n\nFocusTrap.propTypes = {\n selector: PropTypes.string,\n children: defaultChildrenPropTypes.isRequired,\n onDeactivate: PropTypes.func,\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames/bind';\nimport { FocusTrap } from '../../shared/components/focusTrap';\nimport { defaultChildrenPropTypes } from '../../common-prop-types';\nimport { ButtonNew as Button } from '@crayons';\nimport CloseIcon from '@images/x.svg';\n\nexport const Modal = ({\n children,\n size,\n className,\n title,\n prompt,\n sheet,\n centered,\n noBackdrop,\n showHeader = true,\n sheetAlign = 'center',\n backdropDismissible = false,\n allowOverflow = false,\n onClose = () => {},\n focusTrapSelector = '.crayons-modal__box',\n document = window.document,\n}) => {\n const classes = classNames('crayons-modal', {\n [`crayons-modal--${size}`]: size && size !== 'medium',\n [`crayons-modal--${sheetAlign}`]: sheet && sheetAlign !== 'center',\n 'crayons-modal--sheet': sheet,\n 'crayons-modal--prompt': prompt,\n 'crayons-modal--centered': centered && prompt,\n 'crayons-modal--bg-dismissible': !noBackdrop && backdropDismissible,\n 'crayons-modal--overflow-visible': allowOverflow,\n [className]: className,\n });\n\n return (\n \n
\n \n {showHeader && (\n
\n

{title}

\n \n
\n )}\n
{children}
\n
\n {!noBackdrop && (\n \n )}\n \n \n );\n};\n\nModal.displayName = 'Modal';\n\nModal.propTypes = {\n children: defaultChildrenPropTypes.isRequired,\n className: PropTypes.string,\n title: PropTypes.string.isRequired,\n backdrop: PropTypes.bool,\n backdropDismissible: PropTypes.bool,\n prompt: PropTypes.bool,\n centered: PropTypes.bool,\n onClose: PropTypes.func,\n size: PropTypes.oneOf(['small', 'medium', 'large']),\n focusTrapSelector: PropTypes.string,\n sheet: PropTypes.bool,\n sheetAlign: PropTypes.oneOf(['center', 'left', 'right']),\n showHeader: PropTypes.bool,\n};\n","let postscribeImport;\n\nasync function getPostScribe() {\n if (postscribeImport) {\n // Grab the cached import so we're not always fetching it from the network.\n return postscribeImport;\n }\n\n const { default: postscribe } = await import('postscribe');\n postscribeImport = postscribe;\n\n return postscribeImport;\n}\n\nfunction getGistTags(nodes) {\n const gistNodes = [];\n\n for (const node of nodes) {\n if (node.nodeType === 1) {\n if (node.classList.contains('ltag_gist-liquid-tag')) {\n gistNodes.push(node);\n }\n\n gistNodes.push(...node.querySelectorAll('.ltag_gist-liquid-tag'));\n }\n }\n\n return gistNodes;\n}\n\nfunction loadEmbeddedGists(postscribe, gistTags) {\n for (const gistTag of gistTags) {\n const gistWrapper = gistTag.firstElementChild;\n postscribe(gistTag, gistWrapper.outerHTML, {\n beforeWrite(text) {\n return gistTag.childElementCount > 3 ? '' : text;\n },\n });\n gistWrapper.remove();\n }\n}\n\nfunction watchForGistTagInsertion(targetNode, postscribe) {\n const config = { attributes: false, childList: true, subtree: true };\n\n const callback = function (mutationsList) {\n for (const { type, addedNodes } of mutationsList) {\n if (type === 'childList' && addedNodes.length > 0) {\n loadEmbeddedGists(postscribe, getGistTags(addedNodes));\n }\n }\n };\n\n const observer = new MutationObserver(callback);\n observer.observe(targetNode, config);\n\n InstantClick.on('change', () => {\n observer.disconnect();\n });\n\n window.addEventListener('beforeunload', () => {\n observer.disconnect();\n });\n}\n\nexport async function embedGists(targetNode) {\n const postscribe = await getPostScribe();\n\n // Load gist tags that were rendered server-side\n loadEmbeddedGists(\n postscribe,\n document.querySelectorAll('.ltag_gist-liquid-tag'),\n );\n\n watchForGistTagInsertion(targetNode, postscribe);\n}\n","import { validateFileInputs } from '../packs/validateFileInputs';\n\nexport function previewArticle(payload, successCb, failureCb) {\n fetch('/articles/preview', {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'X-CSRF-Token': window.csrfToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n article_body: payload,\n }),\n credentials: 'same-origin',\n })\n .then(async (response) => {\n const payload = await response.json();\n\n if (response.status !== 200) {\n throw payload;\n }\n\n return payload;\n })\n .then(successCb)\n .catch(failureCb);\n}\n\nexport function getArticle() {}\n\nfunction processPayload(payload) {\n const {\n /* eslint-disable no-unused-vars */\n previewShowing,\n helpShowing,\n previewResponse,\n helpHTML,\n imageManagementShowing,\n moreConfigShowing,\n errors,\n /* eslint-enable no-unused-vars */\n ...neededPayload\n } = payload;\n return neededPayload;\n}\n\nexport function submitArticle({ payload, onSuccess, onError }) {\n const method = payload.id ? 'PUT' : 'POST';\n const url = payload.id ? `/articles/${payload.id}` : '/articles';\n fetch(url, {\n method,\n headers: {\n Accept: 'application/json',\n 'X-CSRF-Token': window.csrfToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n article: processPayload(payload),\n }),\n credentials: 'same-origin',\n })\n .then((response) => response.json())\n .then((response) => {\n if (response.current_state_path) {\n onSuccess();\n window.location.replace(response.current_state_path);\n } else {\n onError(response);\n }\n })\n .catch(onError);\n}\n\nfunction generateUploadFormdata(payload) {\n const token = window.csrfToken;\n const formData = new FormData();\n formData.append('authenticity_token', token);\n\n Object.entries(payload.image).forEach(([_, value]) =>\n formData.append('image[]', value),\n );\n\n return formData;\n}\n\nexport function generateMainImage({ payload, successCb, failureCb, signal }) {\n fetch('/image_uploads', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': window.csrfToken,\n },\n body: generateUploadFormdata(payload),\n credentials: 'same-origin',\n signal,\n })\n .then((response) => response.json())\n .then((json) => {\n if (json.error) {\n throw new Error(json.error);\n }\n const { links } = json;\n const { image } = payload;\n return successCb({ links, image });\n })\n .catch((message) => failureCb(message));\n}\n\n/**\n * Processes images for upload.\n *\n * @param {FileList} images Images to be uploaded.\n * @param {Function} handleImageSuccess The handler that runs when the image is uploaded successfully.\n * @param {Function} handleImageFailure The handler that runs when the image upload fails.\n */\nexport function processImageUpload(\n images,\n handleImageUploading,\n handleImageSuccess,\n handleImageFailure,\n) {\n // Currently only one image is supported for upload.\n if (images.length > 0 && validateFileInputs()) {\n const payload = { image: images };\n\n handleImageUploading();\n generateMainImage({\n payload,\n successCb: handleImageSuccess,\n failureCb: handleImageFailure,\n });\n }\n}\n","import PropTypes from 'prop-types';\n\nexport const articleSnippetResultPropTypes = PropTypes.shape({\n body_text: PropTypes.arrayOf(PropTypes.string),\n});\n\nexport const articlePropTypes = PropTypes.shape({\n id: PropTypes.number.isRequired,\n title: PropTypes.string.isRequired,\n path: PropTypes.string.isRequired,\n cloudinary_video_url: PropTypes.string,\n video_duration_in_minutes: PropTypes.string,\n type_of: PropTypes.oneOf(['podcast_episodes']),\n class_name: PropTypes.oneOf(['PodcastEpisode', 'User', 'Article']),\n flare_tag: PropTypes.shape({\n name: PropTypes.string.isRequired,\n bg_color_hex: PropTypes.string,\n text_color_hex: PropTypes.string,\n }),\n tag_list: PropTypes.arrayOf(PropTypes.string),\n cached_tag_list_array: PropTypes.arrayOf(PropTypes.string),\n podcast: PropTypes.shape({\n slug: PropTypes.string.isRequired,\n title: PropTypes.string.isRequired,\n image_url: PropTypes.string.isRequired,\n }),\n user_id: PropTypes.number.isRequired,\n user: PropTypes.shape({\n username: PropTypes.string.isRequired,\n name: PropTypes.string.isRequired,\n }),\n organization: PropTypes.shape({\n name: PropTypes.string.isRequired,\n profile_image_90: PropTypes.string.isRequired,\n slug: PropTypes.string.isRequired,\n }),\n highlight: articleSnippetResultPropTypes,\n public_reactions_count: PropTypes.number,\n reactions_count: PropTypes.number,\n comments_count: PropTypes.number,\n reading_time: PropTypes.number,\n});\n","// These styles are applied to the hidden element we use to measure the height.\n// !important styles are used to ensure no matter what style properties are attached to the given textarea, the hidden textarea will never become visible or cause layout jumps\nconst HIDDEN_TEXTAREA_STYLE = `\nmin-height:0 !important;\nmax-height:none !important;\nheight:0 !important;\nvisibility:hidden !important;\noverflow:hidden !important;\nposition:absolute !important;\nz-index:-1000 !important;\ntop:0 !important;\nright:0 !important\n`;\n\nconst SIZING_STYLE = [\n 'letter-spacing',\n 'line-height',\n 'padding-top',\n 'padding-bottom',\n 'font-family',\n 'font-weight',\n 'font-size',\n 'text-rendering',\n 'text-transform',\n 'width',\n 'text-indent',\n 'padding-left',\n 'padding-right',\n 'border-width',\n 'box-sizing',\n];\n\nlet hiddenTextarea;\n\n/**\n * Helper function to get the height of the textarea based on the current text content\n *\n * @param {HTMLElement} uiTextNode The textarea to measure height of\n *\n * @returns {{height: number}} Object with the calculated height\n */\nexport const calculateTextAreaHeight = (uiTextNode) => {\n if (!hiddenTextarea) {\n hiddenTextarea = document.createElement('textarea');\n document.body.appendChild(hiddenTextarea);\n }\n\n // Copy all CSS properties that have an impact on the height of the content in\n // the textbox\n const {\n paddingSize,\n borderSize,\n boxSizing,\n sizingStyle,\n } = calculateNodeStyling(uiTextNode);\n\n // Need to have the overflow attribute to hide the scrollbar otherwise\n // text-lines will not calculated properly as the shadow will technically be\n // narrower for content\n hiddenTextarea.setAttribute(\n 'style',\n `${sizingStyle};${HIDDEN_TEXTAREA_STYLE}`,\n );\n hiddenTextarea.value = uiTextNode.value || uiTextNode.placeholder || 'x';\n\n const baseHeight = hiddenTextarea.scrollHeight;\n\n if (boxSizing === 'border-box') {\n // border-box: add border, since height = content + padding + border\n return { height: baseHeight + borderSize };\n } else if (boxSizing === 'content-box') {\n // remove padding, since height = content\n return { height: baseHeight - paddingSize };\n }\n\n return { height: baseHeight };\n};\n\nconst calculateNodeStyling = (node) => {\n const style = window.getComputedStyle(node);\n\n const boxSizing =\n style.getPropertyValue('box-sizing') ||\n style.getPropertyValue('-moz-box-sizing') ||\n style.getPropertyValue('-webkit-box-sizing');\n\n const paddingSize =\n parseFloat(style.getPropertyValue('padding-bottom')) +\n parseFloat(style.getPropertyValue('padding-top'));\n\n const borderSize =\n parseFloat(style.getPropertyValue('border-bottom-width')) +\n parseFloat(style.getPropertyValue('border-top-width'));\n\n const sizingStyle = SIZING_STYLE.map(\n (name) => `${name}:${style.getPropertyValue(name)}`,\n ).join(';');\n\n return {\n sizingStyle,\n paddingSize,\n borderSize,\n boxSizing,\n };\n};\n","import { useEffect, useState } from 'preact/hooks';\nimport { calculateTextAreaHeight } from '@utilities/calculateTextAreaHeight';\nimport { debounceAction } from '@utilities/debounceAction';\n\n/**\n * A helper function to get the X/Y coordinates of the current cursor position within an element.\n * For a full explanation see the post by Jhey Tompkins: https://medium.com/@jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a\n *\n * @param {args}\n * @param {args.element} input The DOM element the cursor is to be found within\n * @param {args.number} selectionPoint The current cursor position (e.g. either selectionStart or selectionEnd)\n * @param {args.element} relativeToElement The DOM element the position to be calculated relative to. Defaults to the document body\n *\n * @returns {object} An object with x and y properties (e.g. {x: 10, y: 0})\n *\n * @example\n * const coordinates = getCursorXY(elementRef.current, elementRef.current.selectionStart)\n */\nexport const getCursorXY = ({\n input,\n selectionPoint,\n relativeToElement = document.body,\n}) => {\n const bodyRect = relativeToElement.getBoundingClientRect();\n const elementRect = input.getBoundingClientRect();\n\n const inputY = elementRect.top - bodyRect.top - input.scrollTop;\n const inputX = elementRect.left - bodyRect.left - input.scrollLeft;\n\n // create a dummy element with the computed style of the input\n const div = document.createElement('div');\n const copyStyle = getComputedStyle(input);\n\n for (const property of Object.values(copyStyle)) {\n div.style.setProperty(property, copyStyle.getPropertyValue(property));\n }\n\n // set the div to the correct position\n div.style['position'] = 'absolute';\n div.style['top'] = `${inputY}px`;\n div.style['left'] = `${inputX}px`;\n div.style['opacity'] = 0;\n\n // replace whitespace with '.' when filling the dummy element if it's a single line \n const swap = '.';\n const inputValue =\n input.tagName === 'INPUT' ? input.value.replace(/ /g, swap) : input.value;\n\n // set the div content to that of the textarea up until selection point\n div.textContent = inputValue.substr(0, selectionPoint);\n\n if (input.tagName === 'TEXTAREA') div.style.height = 'auto';\n // if a single line input then the div needs to be single line and not break out like a text area\n if (input.tagName === 'INPUT') div.style.width = 'auto';\n\n // marker element to obtain caret position\n const span = document.createElement('span');\n // give the span the textContent of remaining content so that the recreated dummy element is as close as possible\n span.textContent = inputValue.substr(selectionPoint) || '.';\n\n // append the span marker to the div and the dummy element to the body\n div.appendChild(span);\n relativeToElement.appendChild(div);\n\n // get the marker position, this is the caret position top and left relative to the input\n const { offsetLeft: spanX, offsetTop: spanY } = span;\n\n // remove dummy element\n relativeToElement.removeChild(div);\n\n // return object with the x and y of the caret. account for input positioning so that you don't need to wrap the input\n return {\n x: inputX + spanX,\n y: inputY + spanY,\n };\n};\n\n// TODO: Remove once MentionAutocompleteTextArea removed\nexport const getMentionWordData = () => {};\n\n/**\n * A helper function that searches back to the beginning of the currently typed word (indicated by cursor position) and verifies whether it begins with an '@' symbol for user mention\n *\n * @param {element} textArea The text area or input to inspect the current word of\n * @returns {{isTriggered: boolean, indexOfAutocompleteStart: number}} Object with the word's autocomplete data\n *\n * @example\n * const { isTriggered, indexOfAutocompleteStart } = getAutocompleteWordData({textArea, triggerCharacter: '@'});\n * if (isTriggered) {\n * // Do something\n * }\n */\nexport const getAutocompleteWordData = ({ textArea, triggerCharacter }) => {\n const { selectionStart, value: valueBeforeKeystroke } = textArea;\n\n if (selectionStart === 0 || valueBeforeKeystroke === '') {\n return {\n isTriggered: false,\n indexOfAutocompleteStart: -1,\n };\n }\n\n const indexOfAutocompleteStart = getLastIndexOfCharacter({\n content: valueBeforeKeystroke,\n selectionIndex: selectionStart,\n character: triggerCharacter,\n breakOnCharacters: [' ', '', '\\n'],\n });\n\n return {\n isTriggered: indexOfAutocompleteStart !== -1,\n indexOfAutocompleteStart,\n };\n};\n\n/**\n * Searches backwards through text content for the last occurrence of the given character\n *\n * @param {Object} params\n * @param {string} content The chunk of text to search within\n * @param {number} selectionIndex The starting point to search from\n * @param {string} character The character to search for\n * @param {string[]} breakOnCharacters Any characters which should result in an immediate halt to the search\n * @returns {number} Index of the last occurrence of the character, or -1 if it isn't found\n */\nexport const getLastIndexOfCharacter = ({\n content,\n selectionIndex,\n character,\n breakOnCharacters = [],\n}) => {\n const currentCharacter = content.charAt(selectionIndex);\n const previousCharacter = content.charAt(selectionIndex - 1);\n\n if (currentCharacter === character) {\n return selectionIndex;\n }\n\n if (selectionIndex !== 0 && !breakOnCharacters.includes(previousCharacter)) {\n return getLastIndexOfCharacter({\n content,\n selectionIndex: selectionIndex - 1,\n character,\n breakOnCharacters,\n });\n }\n\n return -1;\n};\n\n/**\n * Searches forwards through text content for the next occurrence of the given character\n *\n * @param {Object} params\n * @param {string} content The chunk of text to search within\n * @param {number} selectionIndex The starting point to search from\n * @param {string} character The character to search for\n * @param {string[]} breakOnCharacters Any characters which should result in an immediate halt to the search\n * @returns {number} Index of the next occurrence of the character, or -1 if it isn't found\n */\nexport const getNextIndexOfCharacter = ({\n content,\n selectionIndex,\n character,\n breakOnCharacters = [],\n}) => {\n const currentCharacter = content.charAt(selectionIndex);\n const nextCharacter = content.charAt(selectionIndex + 1);\n\n if (currentCharacter === character) {\n return selectionIndex;\n }\n\n if (\n selectionIndex <= content.length &&\n !breakOnCharacters.includes(nextCharacter)\n ) {\n return getNextIndexOfCharacter({\n content,\n selectionIndex: selectionIndex + 1,\n character,\n breakOnCharacters,\n });\n }\n\n return -1;\n};\n\n/**\n * Counts how many new lines come immediately before the user's current selection start\n * @param {object} args\n * @param {number} args.selectionStart The index of user's current selection start\n * @param {string} args.value The value of the textarea\n *\n * @returns {number} Number of new lines directly before selection start\n */\nexport const getNumberOfNewLinesPrecedingSelection = ({\n selectionStart,\n value,\n}) => {\n if (selectionStart === 0) {\n return 0;\n }\n\n let count = 0;\n let searchIndex = selectionStart - 1;\n\n while (searchIndex >= 0 && value.charAt(searchIndex) === '\\n') {\n count++;\n searchIndex--;\n }\n\n return count;\n};\n\n/**\n * Counts how many new lines come immediately after the user's current selection end\n *\n * @param {object} args\n * @param {number} args.selectionEnd The index of user's current selection end\n * @param {string} args.value The value of the textarea\n *\n * @returns {number} the count of new line characters immediately following selection\n */\nexport const getNumberOfNewLinesFollowingSelection = ({\n selectionEnd,\n value,\n}) => {\n if (selectionEnd === value.length) {\n return 0;\n }\n\n let count = 0;\n let searchIndex = selectionEnd;\n\n while (searchIndex < value.length && value.charAt(searchIndex) === '\\n') {\n count++;\n searchIndex++;\n }\n\n return count;\n};\n\n/**\n * Retrieve data about the user's current text selection\n *\n * @param {Object} params\n * @param {number} selectionStart The start point of user's selection\n * @param {number} selectionEnd The end point of user's selection\n * @param {string} value The current value of the textarea\n * @returns {Object} object containing the text chunks before and after insertion, and the currently selected text\n */\nexport const getSelectionData = ({ selectionStart, selectionEnd, value }) => ({\n textBeforeSelection: value.substring(0, selectionStart),\n textAfterSelection: value.substring(selectionEnd, value.length),\n selectedText: value.substring(selectionStart, selectionEnd),\n});\n\n/**\n * This hook can be used to keep the height of a textarea in step with the current content height, avoiding a scrolling textarea.\n * An optional array of additional elements can be set. If provided, all elements will be set to the greatest content height.\n * Optionally, it can be specified to also constrain the max-height to the content height. Otherwise the max-height will continue to be managed only by the textarea's CSS\n *\n * @example\n *\n * const { setTextArea } = useTextAreaAutoResize();\n * setTextArea(myTextAreaRef.current);\n * setAdditionalElements([myOtherElement.current]);\n */\nexport const useTextAreaAutoResize = () => {\n const [textArea, setTextArea] = useState(null);\n const [constrainToContentHeight, setConstrainToContentHeight] =\n useState(false);\n const [additionalElements, setAdditionalElements] = useState([]);\n\n useEffect(() => {\n if (!textArea) {\n return;\n }\n\n const resizeTextArea = () => {\n const allElements = [textArea, ...additionalElements];\n\n const allContentHeights = allElements.map(\n (element) => calculateTextAreaHeight(element).height,\n );\n\n const height = Math.max(...allContentHeights);\n const newHeight = `${height}px`;\n\n allElements.forEach((element) => {\n element.style['min-height'] = newHeight;\n if (constrainToContentHeight) {\n // Don't allow the textarea to grow to a size larger than the content\n element.style['max-height'] = newHeight;\n }\n });\n };\n\n // Resize on first attach\n resizeTextArea();\n\n // Resize on window size changes\n const resizeCallback = debounceAction(() => resizeTextArea(), 300);\n const resizeObserver = new ResizeObserver(resizeCallback);\n resizeObserver.observe(textArea);\n\n // Resize on subsequent value changes\n textArea.addEventListener('input', resizeTextArea);\n\n return () => {\n resizeObserver.disconnect();\n textArea.removeEventListener('input', resizeTextArea);\n };\n }, [textArea, additionalElements, constrainToContentHeight]);\n\n return { setTextArea, setAdditionalElements, setConstrainToContentHeight };\n};\n","export * from './Button';\n","import { h } from 'preact';\nimport { useState } from 'preact/hooks';\nimport PropTypes from 'prop-types';\nimport { defaultChildrenPropTypes } from '../../common-prop-types';\n\nfunction getAdditionalClassNames({\n variant,\n className,\n contentType,\n size,\n inverted,\n disabled,\n tooltip,\n}) {\n let additionalClassNames = '';\n\n if (variant && variant.length > 0 && variant !== 'primary') {\n additionalClassNames += ` crayons-btn--${variant}`;\n }\n\n if (size && size.length > 0 && size !== 'default') {\n additionalClassNames += ` crayons-btn--${size}`;\n }\n\n if (contentType && contentType.length > 0 && contentType !== 'text') {\n additionalClassNames += ` crayons-btn--${contentType}`;\n }\n\n if (disabled) {\n additionalClassNames += ' crayons-btn--disabled';\n }\n\n if (inverted) {\n additionalClassNames += ' crayons-btn--inverted';\n }\n\n if (className && className.length > 0) {\n additionalClassNames += ` ${className}`;\n }\n\n if (tooltip) {\n additionalClassNames += ` crayons-tooltip__activator`;\n }\n\n return additionalClassNames;\n}\n\nexport const Button = (props) => {\n const {\n children,\n variant = 'primary',\n tagName,\n inverted,\n contentType,\n size,\n className,\n icon,\n url,\n buttonType,\n disabled,\n onClick,\n onMouseOver,\n onMouseOut,\n onFocus,\n onBlur,\n onKeyUp,\n tabIndex,\n title,\n tooltip,\n ...restOfProps\n } = props;\n\n const [suppressTooltip, setSuppressTooltip] = useState(false);\n\n const handleKeyUp = (event) => {\n onKeyUp?.(event);\n if (!tooltip) {\n return;\n }\n setSuppressTooltip(event.key === 'Escape');\n };\n\n const ComponentName = tagName;\n const Icon = icon;\n const otherProps =\n tagName === 'button'\n ? { type: buttonType, disabled }\n : { href: disabled ? undefined : url };\n\n return (\n \n {contentType !== 'text' && contentType !== 'icon-right' && Icon && (\n \n )}\n {(contentType === 'text' ||\n contentType === 'icon-left' ||\n contentType === 'icon-right') &&\n children}\n {contentType !== 'text' && contentType === 'icon-right' && Icon && (\n \n )}\n {tooltip ? (\n \n {tooltip}\n \n ) : null}\n \n );\n};\n\nButton.displayName = 'Button';\n\nButton.defaultProps = {\n className: undefined,\n icon: undefined,\n url: undefined,\n buttonType: 'button',\n disabled: false,\n inverted: false,\n onClick: undefined,\n onMouseOver: undefined,\n onMouseOut: undefined,\n onFocus: undefined,\n onBlur: undefined,\n tabIndex: undefined,\n title: undefined,\n tagName: 'button',\n size: 'default',\n contentType: 'text',\n variant: 'primary',\n};\n\nButton.propTypes = {\n children: defaultChildrenPropTypes,\n variant: PropTypes.oneOf([\n 'primary',\n 'secondary',\n 'outlined',\n 'danger',\n 'ghost',\n 'ghost-brand',\n 'ghost-success',\n 'ghost-warning',\n 'ghost-danger',\n ]),\n contentType: PropTypes.oneOf([\n 'text',\n 'icon-left',\n 'icon-right',\n 'icon',\n 'icon-rounded',\n ]).isRequired,\n inverted: PropTypes.bool,\n tagName: PropTypes.oneOf(['a', 'button']).isRequired,\n className: PropTypes.string,\n icon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),\n url: PropTypes.string,\n buttonType: PropTypes.string,\n disabled: PropTypes.bool,\n size: PropTypes.oneOf(['default', 's', 'l', 'xl']).isRequired,\n onClick: PropTypes.func,\n onMouseOver: PropTypes.func,\n onMouseOut: PropTypes.func,\n onFocus: PropTypes.func,\n onBlur: PropTypes.func,\n tabIndex: PropTypes.number,\n title: PropTypes.string,\n tooltip: PropTypes.node,\n};\n","import { h } from 'preact';\n\nexport const Spinner = () => (\n \n \n \n);\n","import { h, Component } from 'preact';\nimport PropTypes from 'prop-types';\nimport { SnackbarItem } from './SnackbarItem';\n\nlet snackbarItems = [];\n\nexport function addSnackbarItem(snackbarItem) {\n if (!Array.isArray(snackbarItem.actions)) {\n snackbarItem.actions = []; // eslint-disable-line no-param-reassign\n }\n\n snackbarItems.push(snackbarItem);\n}\n\nexport class Snackbar extends Component {\n state = {\n snacks: [],\n };\n\n pollingId;\n\n paused = false;\n\n pauseLifespan;\n\n resumeLifespan;\n\n componentDidMount() {\n this.initializePolling();\n }\n\n componentDidUpdate() {\n if (!this.pauseLifespan) {\n this.pauseLifespan = (_event) => {\n this.paused = true;\n };\n\n this.resumeLifespan = (event) => {\n event.stopPropagation();\n this.paused = false;\n };\n\n this.element.addEventListener('mouseover', this.pauseLifespan);\n this.element.addEventListener('mouseout', this.resumeLifespan, true);\n }\n }\n\n componentWillUnmount() {\n if (this.element) {\n this.element.removeEventListener('mouseover', this.pauseLifespan);\n this.element.addEventListener('mouseout', this.resumeLifespan);\n }\n }\n\n initializePolling() {\n const { pollingTime, lifespan } = this.props;\n\n this.pollingId = setInterval(() => {\n if (snackbarItems.length > 0) {\n // Need to add the lifespan to snackbar items because each second that goes by, we\n // decrease the lifespan until it is no more.\n const newSnacks = snackbarItems.map((snackbarItem) => ({\n ...snackbarItem,\n lifespan,\n }));\n\n snackbarItems = [];\n\n this.updateSnackbarItems(newSnacks);\n\n // Start the lifespan countdowns for each new snackbar item.\n newSnacks.forEach((snack) => {\n // eslint-disable-next-line no-param-reassign\n snack.lifespanTimeoutId = setTimeout(() => {\n this.decreaseLifespan(snack);\n }, 1000);\n\n if (snack.addCloseButton) {\n // Adds an optional close button if addDefaultACtion is true.\n snack.actions.push({\n text: 'Dismiss',\n handler: () => {\n this.setState((prevState) => {\n return {\n prevState,\n snacks: prevState.snacks.filter(\n (potentialSnackToFilterOut) =>\n potentialSnackToFilterOut !== snack,\n ),\n };\n });\n },\n });\n }\n });\n }\n }, pollingTime);\n }\n\n updateSnackbarItems(newSnacks) {\n this.setState((prevState) => {\n let updatedSnacks = [...prevState.snacks, ...newSnacks];\n\n if (updatedSnacks.length > 3) {\n const snacksToBeDiscarded = updatedSnacks.slice(\n 0,\n updatedSnacks.length - 3,\n );\n\n snacksToBeDiscarded.forEach(({ lifespanTimeoutId }) => {\n clearTimeout(lifespanTimeoutId);\n });\n\n updatedSnacks = updatedSnacks.slice(updatedSnacks.length - 3);\n }\n\n return { ...prevState, snacks: updatedSnacks };\n });\n }\n\n decreaseLifespan(snack) {\n /* eslint-disable no-param-reassign */\n if (!this.paused && snack.lifespan === 0) {\n clearTimeout(snack.lifespanTimeoutId);\n\n this.setState((prevState) => {\n const snacks = prevState.snacks.filter(\n (currentSnack) => currentSnack !== snack,\n );\n\n return {\n ...prevState,\n snacks,\n };\n });\n\n return;\n }\n\n if (!this.paused) {\n snack.lifespan -= 1;\n }\n\n snack.lifespanTimeoutId = setTimeout(() => {\n this.decreaseLifespan(snack);\n }, 1000);\n /* eslint-enable no-param-reassign */\n }\n\n render() {\n const { snacks } = this.state;\n\n return (\n 0 ? 'crayons-snackbar' : 'hidden'}\n ref={(element) => {\n this.element = element;\n }}\n >\n {snacks.map(({ message, actions = [] }, index) => (\n \n ))}\n \n );\n }\n}\n\nSnackbar.defaultProps = {\n lifespan: 5,\n pollingTime: 300,\n};\n\nSnackbar.displayName = 'Snackbar';\n\nSnackbar.propTypes = {\n lifespan: PropTypes.number,\n pollingTime: PropTypes.number,\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\n\n/**\n * Component used to display user details in the Autocomplete dropdown\n *\n * @param {object} props\n * @param {string} props.name The user's name\n * @param {string} props.profile_image_90 The src of the user's profile image\n * @param {string} props.username The user's username\n */\nexport const UserListItemContent = ({ name, profile_image_90, username }) => (\n
\n \n \"\"\n \n\n
\n

{name}

\n

{`@${username}`}

\n
\n
\n);\n\nUserListItemContent.propTypes = {\n name: PropTypes.string.isRequired,\n username: PropTypes.string.isRequired,\n profile_image_90: PropTypes.string.isRequired,\n};\n","import { h } from 'preact';\nimport { useRef, useLayoutEffect, useReducer, useEffect } from 'preact/hooks';\nimport { forwardRef, createPortal } from 'preact/compat';\nimport { UserListItemContent } from './UserListItemContent';\nimport { useMediaQuery, BREAKPOINTS } from '@components/useMediaQuery';\nimport { isInViewport } from '@utilities/viewport';\n\nimport {\n useTextAreaAutoResize,\n getAutocompleteWordData,\n getCursorXY,\n} from '@utilities/textAreaUtils';\n\n// Used to ensure dropdown appears just below search text\nconst DROPDOWN_VERTICAL_OFFSET = '1.5rem';\nconst EMPTY_STATE_MESSAGE = 'No results found';\nconst MINIMUM_SEARCH_CHARS = 2;\n\nconst KEYS = {\n UP: 'ArrowUp',\n DOWN: 'ArrowDown',\n ENTER: 'Enter',\n ESCAPE: 'Escape',\n};\n\n/**\n * Helper function to copy all styles and attributes from the original textarea to the new autocomplete one\n *\n * @param {object} options\n * @param {element} options.originalTextArea The textarea DOM element that should be replaced/removed\n * @param {element} options.newTextArea The textarea DOM element containing the autocomplete functionality. It will receive all attributes and styles of the original node.\n */\nconst replaceTextArea = ({ originalTextArea, newTextArea }) => {\n const { attributes } = originalTextArea;\n const { cssText } = document.defaultView.getComputedStyle(\n originalTextArea,\n '',\n );\n\n // Make sure all attributes are copied over\n Object.keys(attributes).forEach((attributeKey) => {\n newTextArea.setAttribute(\n attributes[attributeKey].name,\n attributes[attributeKey].value,\n );\n });\n\n // Make sure all styles are copied over\n newTextArea.style.cssText = cssText;\n // Make sure no transition replays when the new textarea is mounted\n newTextArea.style.transition = 'none';\n // Copy any initial value\n newTextArea.value = originalTextArea.value;\n\n // We need to manually remove the original element, as Preact's diffing algorithm won't replace it in render\n originalTextArea.remove();\n};\n\n/**\n * Helper function to merge any additional ref passed to the textArea with the ref used internally by this component.\n *\n * @param {Array} refs Array of all references\n */\nconst mergeInputRefs = (refs) => (value) => {\n refs.forEach((ref) => {\n if (ref) {\n ref.current = value;\n }\n });\n};\n\nconst reducer = (state, action) => {\n switch (action.type) {\n case 'setIsComboboxMode':\n return { ...state, isComboboxMode: action.payload };\n case 'setSuggestions':\n return { ...state, suggestions: action.payload };\n case 'setDropdownPositionPoints':\n return { ...state, dropdownPositionPoints: action.payload };\n case 'setActiveDescendentIndex':\n return { ...state, activeDescendentIndex: action.payload };\n case 'setSuppressPopover':\n return { ...state, suppressPopover: action.payload };\n case 'setEmptyStateMessage':\n return { ...state, emptyStateMessage: action.payload };\n case 'setIgnoreBlur':\n return { ...state, ignoreBlur: action.payload };\n case 'exitComboboxMode':\n return {\n ...state,\n suggestions: [],\n activeDescendentIndex: null,\n isComboboxMode: false,\n };\n\n default:\n return state;\n }\n};\n\n/**\n * Renders a textarea with enhanced autocomplete functionality.\n * Autocomplete searching will start when user types the given trigger character, with suggestions fetched via fetchSuggestions callback.\n * Can optionally replace an existing textarea, passed as the replaceElement prop.\n */\nexport const AutocompleteTriggerTextArea = forwardRef(\n (\n {\n id,\n triggerCharacter,\n autoResize = false,\n onChange,\n onBlur,\n fetchSuggestions,\n searchInstructionsMessage,\n maxSuggestions,\n replaceElement,\n ...inputProps\n },\n forwardedRef,\n ) => {\n const [state, dispatch] = useReducer(reducer, {\n isComboboxMode: false,\n suggestions: [],\n dropdownPositionPoints: {\n x: 0,\n y: 0,\n },\n activeDescendentIndex: null,\n suppressPopover: false,\n emptyStateMessage: searchInstructionsMessage,\n ignoreBlur: false,\n });\n\n const {\n isComboboxMode,\n suggestions,\n dropdownPositionPoints,\n activeDescendentIndex,\n suppressPopover,\n emptyStateMessage,\n ignoreBlur,\n } = state;\n\n const isSmallScreen = useMediaQuery(`(max-width: ${BREAKPOINTS.Small}px)`);\n\n const inputRef = useRef(null);\n const popoverRef = useRef(null);\n const wrapperRef = useRef(null);\n\n const { setTextArea, setAdditionalElements } = useTextAreaAutoResize();\n\n useEffect(() => {\n if (activeDescendentIndex !== null) {\n const { current: popover } = popoverRef;\n const activeItem = popover?.querySelector('[aria-selected=\"true\"]');\n if (!popover || !activeItem) {\n return;\n }\n\n if (!isInViewport({ element: activeItem })) {\n activeItem.scrollIntoView(false);\n }\n }\n }, [activeDescendentIndex]);\n\n useLayoutEffect(() => {\n if (autoResize && inputRef.current) {\n setTextArea(inputRef.current);\n setAdditionalElements([wrapperRef.current]);\n }\n }, [autoResize, setTextArea, setAdditionalElements]);\n\n useLayoutEffect(() => {\n const { current: enhancedTextArea } = inputRef;\n\n if (enhancedTextArea && replaceElement) {\n replaceTextArea({\n originalTextArea: replaceElement,\n newTextArea: enhancedTextArea,\n });\n enhancedTextArea.focus({ preventScroll: true });\n }\n }, [replaceElement]);\n\n const handleInputChange = () => {\n const { current: currentInput } = inputRef;\n\n const {\n isTriggered: isSearching,\n indexOfAutocompleteStart: indexOfSearchStart,\n } = getAutocompleteWordData({\n textArea: currentInput,\n triggerCharacter,\n });\n\n dispatch({ type: 'setIsComboboxMode', payload: isSearching });\n\n if (!isSearching) {\n dispatch({ type: 'setSuggestions', payload: [] });\n return;\n }\n\n // Fetch suggestions\n const { selectionStart, value: currentValue } = currentInput;\n\n // Search term begins after the triggerCharacter\n const searchTermStartPosition = indexOfSearchStart + 1;\n\n const searchTerm = currentValue.substring(\n searchTermStartPosition,\n selectionStart,\n );\n\n if (searchTerm.length >= MINIMUM_SEARCH_CHARS) {\n fetchSuggestions(searchTerm).then((suggestions) => {\n if (maxSuggestions && suggestions.length > maxSuggestions) {\n dispatch({\n type: 'setSuggestions',\n payload: suggestions.slice(0, maxSuggestions),\n });\n return;\n }\n dispatch({ type: 'setSuggestions', payload: suggestions });\n });\n\n dispatch({\n type: 'setEmptyStateMessage',\n payload: EMPTY_STATE_MESSAGE,\n });\n } else {\n dispatch({\n type: 'setEmptyStateMessage',\n payload: searchInstructionsMessage,\n });\n }\n\n // Ensure dropdown is properly positioned\n const { x: cursorX, y } = getCursorXY({\n input: currentInput,\n selectionPoint: indexOfSearchStart,\n });\n const textAreaX = currentInput.offsetLeft;\n\n // On small screens always show dropdown at start of textarea\n const dropdownX = isSmallScreen ? textAreaX : cursorX;\n\n dispatch({\n type: 'setDropdownPositionPoints',\n payload: { x: dropdownX, y },\n });\n };\n\n const handleKeyDown = (e) => {\n // If we are not in combobox mode, ignore\n if (!isComboboxMode) {\n return;\n }\n\n switch (e.key) {\n case KEYS.DOWN:\n e.preventDefault();\n\n if (\n activeDescendentIndex !== null &&\n activeDescendentIndex < suggestions.length - 1\n ) {\n dispatch({\n type: 'setActiveDescendentIndex',\n payload: activeDescendentIndex + 1,\n });\n } else {\n dispatch({ type: 'setActiveDescendentIndex', payload: 0 });\n }\n break;\n case KEYS.UP:\n e.preventDefault();\n dispatch({\n type: 'setActiveDescendentIndex',\n payload:\n activeDescendentIndex >= 1\n ? activeDescendentIndex - 1\n : suggestions.length - 1,\n });\n\n break;\n case KEYS.ENTER:\n e.preventDefault();\n if (activeDescendentIndex !== null) {\n selectSuggestion(suggestions[activeDescendentIndex]);\n }\n break;\n case KEYS.ESCAPE:\n e.preventDefault();\n // Temporarily close the popover until next keypress\n dispatch({ type: 'setSuppressPopover', payload: true });\n\n return;\n }\n dispatch({ type: 'setSuppressPopover', payload: false });\n };\n\n // If a user clicks away from an in-progress search, we can assume they no longer wish to keep searching\n const handleTextAreaClicked = () => dispatch({ type: 'exitComboboxMode' });\n\n // The textarea blurs when an option is clicked from the dropdown suggestions, in which case we don't want to\n // trigger the behaviour for the user having left the textarea completely, hence the `ignoreBlur` boolean.\n const handleBlur = () => {\n if (!ignoreBlur) {\n dispatch({ type: 'exitComboboxMode' });\n return;\n }\n dispatch({ type: 'setIgnoreBlur', payload: false });\n };\n\n const selectSuggestion = (suggestion) => {\n const { current: currentInput } = inputRef;\n const { indexOfAutocompleteStart: indexOfSearchStart } =\n getAutocompleteWordData({\n textArea: currentInput,\n triggerCharacter,\n });\n\n const currentSearchTerm = currentInput.value.substring(\n indexOfSearchStart,\n currentInput.selectionStart,\n );\n\n // We try to update the textArea with document.execCommand (so that the change is added to undo queue),\n // which requires the contentEditable attribute to be true. The value is later toggled back to 'false'.\n currentInput.contentEditable = 'true';\n // Input blurs when user clicks an option with the mouse\n currentInput.focus();\n currentInput.setSelectionRange(\n indexOfSearchStart,\n indexOfSearchStart + currentSearchTerm.length,\n );\n\n try {\n document.execCommand(\n 'insertText',\n false,\n `${triggerCharacter}${suggestion.value} `,\n );\n } catch {\n // In the event of any error using execCommand, we make sure the text area updates (but undo queue will not)\n const { value: currentValue } = currentInput;\n const newTextAreaValue = `${currentValue.substring(\n 0,\n indexOfSearchStart,\n )}${triggerCharacter}${suggestion.value}${currentValue.substring(\n indexOfSearchStart + currentSearchTerm.length,\n )} `;\n currentInput.value = newTextAreaValue;\n }\n\n currentInput.contentEditable = 'false';\n\n // Clear suggestions\n dispatch({ type: 'exitComboboxMode' });\n };\n\n const comboboxProps = isComboboxMode\n ? {\n role: 'combobox',\n 'aria-haspopup': 'listbox',\n 'aria-expanded': isComboboxMode,\n 'aria-owns': `${id}-listbox`,\n 'aria-activedescendant': `${id}-suggestion-${activeDescendentIndex}`,\n }\n : {};\n\n return (\n \n {/* We use an assertive live region to alert screen reader users typing will now result in a search */}\n \n {isComboboxMode ? searchInstructionsMessage : ''}\n \n\n {\n onChange?.(e);\n handleInputChange(e);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n handleBlur();\n }}\n onKeyDown={handleKeyDown}\n onClick={handleTextAreaClicked}\n />\n {isComboboxMode && !suppressPopover\n ? createPortal(\n \n {suggestions && suggestions.length > 0 ? (\n
    \n {suggestions.map((suggestion, index) => (\n // Disabled as the key handler is attached to the textarea\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events\n selectSuggestion(suggestion)}\n onMouseDown={() =>\n dispatch({ type: 'setIgnoreBlur', payload: true })\n }\n >\n \n \n ))}\n
\n ) : (\n \n {emptyStateMessage}\n \n )}\n ,\n document.querySelector('body'),\n )\n : null}\n \n );\n },\n);\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { ButtonNew as Button } from '@crayons';\nimport CopyIcon from '@images/copy.svg';\n\nfunction linksToMarkdownForm(imageLinks) {\n return imageLinks\n .map((imageLink) => `![Image description](${imageLink})`)\n .join('\\n');\n}\n\nexport const ClipboardButton = ({\n onCopy,\n imageUrls,\n showCopyMessage = false,\n}) => (\n
\n \n \n {showCopyMessage ? 'Copied!' : 'Copy...'}\n \n
\n);\n\nClipboardButton.displayName = 'ClipboardButton';\n\nClipboardButton.propTypes = {\n onCopy: PropTypes.func.isRequired,\n imageUrls: PropTypes.arrayOf(PropTypes.string).isRequired,\n showCopyMessage: PropTypes.bool.isRequired,\n};\n","import { Fragment, h } from 'preact';\nimport { useReducer, useEffect, useState } from 'preact/hooks';\nimport { generateMainImage } from '../actions';\nimport { validateFileInputs } from '../../packs/validateFileInputs';\nimport { addSnackbarItem } from '../../Snackbar';\nimport { ClipboardButton } from './ClipboardButton';\nimport { copyToClipboard, isNativeIOS } from '@utilities/runtime';\nimport { ButtonNew as Button, Spinner, Icon } from '@crayons';\nimport ImageIcon from '@images/image.svg';\nimport CancelIcon from '@images/x.svg';\n\nconst SpinnerOrCancel = () => (\n \n \n \n \n);\n\nfunction imageUploaderReducer(state, action) {\n const { type, payload } = action;\n\n switch (type) {\n case 'uploading_image':\n return {\n ...state,\n uploadErrorMessage: null,\n uploadingImage: true,\n insertionImageUrls: [],\n };\n\n case 'upload_error':\n return {\n ...state,\n insertionImageUrls: [],\n uploadErrorMessage: payload.errorMessage,\n uploadingImage: false,\n };\n\n case 'upload_image_success':\n return {\n ...state,\n insertionImageUrls: payload.insertionImageUrls,\n uploadingImage: false,\n uploadErrorMessage: null,\n };\n\n default:\n return state;\n }\n}\n\nfunction initNativeImagePicker(e) {\n e.preventDefault();\n window.ForemMobile?.injectNativeMessage('imageUpload', {\n action: 'imageUpload',\n });\n}\n\nconst NativeIosV1ImageUpload = ({ uploadingImage }) => (\n \n {!uploadingImage && (\n \n Upload image\n \n )}\n \n);\n\n/**\n * The V2 editor uses a toolbar button press to trigger a visually hidden file input.\n *\n * @param {object} props\n * @param {object} props.buttonProps Any props to be added to the trigger button\n * @param {function} props.handleInsertionImageUpload Callback to handle image upload\n * @param {boolean} props.uploadingImage Is an image currently being uploaded\n * @param {boolean} props.useNativeUpload Should iOS native upload functionality be used\n * @param {function} props.handleNativeMessage Callback for iOS native upload message handling\n * @param {string} props.uploadErrorMessage Error message to be displayed\n *\n */\nconst V2EditorImageUpload = ({\n buttonProps,\n handleInsertionImageUpload,\n uploadingImage,\n useNativeUpload,\n handleNativeMessage,\n uploadErrorMessage,\n}) => {\n useEffect(() => {\n if (uploadErrorMessage) {\n addSnackbarItem({\n message: uploadErrorMessage,\n addCloseButton: true,\n });\n }\n }, [uploadErrorMessage]);\n\n const [abortRequestController, setAbortRequestController] = useState(null);\n\n const startNewRequest = (e) => {\n const controller = new AbortController();\n setAbortRequestController(controller);\n handleInsertionImageUpload(e, controller.signal);\n };\n\n const cancelRequest = () => {\n abortRequestController.abort();\n setAbortRequestController(null);\n };\n\n const { tooltip: actionTooltip } = buttonProps;\n\n return (\n \n {useNativeUpload ? (\n \n ) : (\n \n )}\n {uploadingImage ? (\n \n ) : (\n {\n buttonProps.onClick?.(e);\n useNativeUpload\n ? initNativeImagePicker(e)\n : document.getElementById('image-upload-field').click();\n }}\n aria-label=\"Upload image\"\n tooltip={actionTooltip}\n />\n )}\n \n );\n};\n\n/**\n * The V1 Editor uses a more detailed image upload UI, displaying errors and markdown text inline\n *\n * @param {object} props\n * @param {boolean} props.uploadingImage Is an image currently being uploaded\n * @param {boolean} props.useNativeUpload Should iOS native upload functionality be used\n * @param {function} props.handleNativeMessage Callback for iOS native upload message handling\n * @param {function} props.handleInsertionImageUpload Callback to handle image upload\n * @param {string[]} props.insertionImageUrls URLs of successfully uploaded images\n * @param {string} props.uploadErrorMessage Error message to be displayed\n *\n * @returns\n */\nconst V1EditorImageUpload = ({\n uploadingImage,\n useNativeUpload,\n handleNativeMessage,\n handleInsertionImageUpload,\n insertionImageUrls,\n uploadErrorMessage,\n}) => {\n const [showCopiedImageText, setShowCopiedImageText] = useState(false);\n\n useEffect(() => {\n if (uploadingImage) {\n setShowCopiedImageText(false);\n }\n }, [uploadingImage]);\n\n const copyText = () => {\n const imageMarkdownInput = document.getElementById(\n 'image-markdown-copy-link-input',\n );\n\n copyToClipboard(imageMarkdownInput.value)\n .then(() => {\n setShowCopiedImageText(true);\n })\n .catch((error) => {\n addSnackbarItem({\n message: error,\n addCloseButton: true,\n });\n Honeybadger.notify(error);\n });\n };\n return (\n
\n {uploadingImage && (\n \n Uploading...\n \n )}\n\n {useNativeUpload ? (\n \n ) : uploadingImage ? null : (\n \n \n \n )}\n\n {insertionImageUrls.length > 0 && (\n \n )}\n\n {uploadErrorMessage ? (\n {uploadErrorMessage}\n ) : null}\n
\n );\n};\n\n/**\n * Image Uploader feature for editor forms\n *\n * @param {object} props\n * @param {string} props.editorVersion The current editor version being used\n * @param {object} props.buttonProps Any additional props to be added to upload image button (v2 editor only)\n * @param {function} props.onImageUploadStart Callback for when image upload begins\n * @param {function} props.onImageUploadSuccess Callback for when image upload succeeds\n * @param {function} props.onImageUploadError Callback for when image upload fails\n *\n */\nexport const ImageUploader = ({\n editorVersion = 'v2',\n buttonProps = {},\n onImageUploadStart,\n onImageUploadSuccess,\n onImageUploadError,\n}) => {\n useEffect(() => {\n // Native Bridge messages come through ForemMobile events\n document.addEventListener('ForemMobile', handleNativeMessage);\n\n // Cleanup afterwards\n return () =>\n document.removeEventListener('ForemMobile', handleNativeMessage);\n });\n\n const [state, dispatch] = useReducer(imageUploaderReducer, {\n insertionImageUrls: [],\n uploadErrorMessage: null,\n uploadingImage: false,\n });\n\n const { uploadingImage, uploadErrorMessage, insertionImageUrls } = state;\n\n function onUploadError(error) {\n onImageUploadError?.();\n dispatch({\n type: 'upload_error',\n payload: { errorMessage: error.message },\n });\n }\n\n function handleInsertionImageUpload(e, abortSignal) {\n const { files } = e.target;\n\n if (files.length > 0 && validateFileInputs()) {\n const payload = { image: files };\n dispatch({\n type: 'uploading_image',\n });\n\n onImageUploadStart?.();\n generateMainImage({\n payload,\n successCb: handleInsertImageUploadSuccess,\n failureCb: onUploadError,\n signal: abortSignal,\n });\n }\n }\n\n function handleInsertImageUploadSuccess(response) {\n dispatch({\n type: 'upload_image_success',\n payload: { insertionImageUrls: response.links },\n });\n\n onImageUploadSuccess?.(`![Image description](${response.links})`);\n\n document.getElementById('upload-success-info').innerText =\n 'image upload complete';\n }\n\n function handleNativeMessage(e) {\n const message = JSON.parse(e.detail);\n if (message.namespace !== 'imageUpload') {\n return;\n }\n\n switch (message.action) {\n case 'uploading':\n onImageUploadStart?.();\n dispatch({\n type: 'uploading_image',\n });\n break;\n case 'error':\n onImageUploadError?.();\n dispatch({\n type: 'upload_error',\n payload: { errorMessage: message.error },\n });\n break;\n case 'success':\n onImageUploadSuccess?.(`![Image description](${message.link})`);\n dispatch({\n type: 'upload_image_success',\n payload: { insertionImageUrls: [message.link] },\n });\n break;\n }\n }\n\n // When the component is rendered in an environment that supports a native\n // image picker for image upload we want to add the aria-label attr and the\n // onClick event to the UI button. This event will kick off the native UX.\n // The props are unwrapped (using spread operator) in the button below\n const useNativeUpload = isNativeIOS('imageUpload');\n\n return (\n \n \n\n {editorVersion === 'v2' ? (\n \n ) : (\n \n )}\n \n );\n};\n\nImageUploader.displayName = 'ImageUploader';\n","import ahoy from 'ahoy.js';\n\n// * Create an ahoy event that will track a click on the\n// * passed in element.\n// *\n// * @param {string} elementId A unique identifier to identify the element that is being tracked\n// */\nexport function trackCommentClicks(elementId) {\n document\n .getElementById(elementId)\n ?.addEventListener('click', ({ target }) => {\n const relevantNode = getTrackingNode(target, '[data-tracking-name]');\n\n if (relevantNode) {\n ahoy.track('Comment section click', {\n page: location.href,\n element: relevantNode.dataset?.trackingName,\n });\n }\n });\n}\n\n// * Create an ahoy event that will track a click on the\n// * passed in element.\n// *\n// * @param {string} elementId A unique identifier to identify the element that is being tracked\n// */\nexport function trackCreateAccountClicks(elementId) {\n document\n .getElementById(elementId)\n ?.addEventListener('click', ({ target }) => {\n const relevantNode = getTrackingNode(target, '[data-tracking-id]');\n if (relevantNode) {\n ahoy.track('Clicked on Create Account', {\n version: 0.1,\n page: location.href,\n source: relevantNode.dataset?.trackingSource,\n });\n }\n });\n}\n\nfunction getTrackingNode(target, trackingElement) {\n // We check for any parent container with a trackingElement attribute, as otherwise\n // SVGs inside buttons can cause events to be missed\n const relevantNode = target.closest(trackingElement);\n return relevantNode;\n}\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { useState } from 'preact/hooks';\nimport classNames from 'classnames/bind';\nimport { defaultChildrenPropTypes } from '../../common-prop-types/default-children-prop-types';\nimport { Icon } from '@crayons';\n\nexport const ButtonNew = (props) => {\n const {\n children,\n variant = 'default',\n icon,\n rounded,\n destructive,\n type = 'button',\n className,\n tooltip,\n onKeyUp,\n ...otherProps\n } = props;\n\n const [suppressTooltip, setSuppressTooltip] = useState(false);\n\n const handleKeyUp = (event) => {\n onKeyUp?.(event);\n if (!tooltip) {\n return;\n }\n setSuppressTooltip(event.key === 'Escape');\n };\n\n const classes = classNames('c-btn', {\n [`c-btn--${variant}`]: variant && variant !== 'default',\n 'c-btn--destructive': destructive && variant !== 'secondary',\n 'c-btn--icon-left': icon && children,\n 'c-btn--icon-alone': icon && !children,\n 'crayons-tooltip__activator': tooltip,\n 'radius-full': rounded,\n [className]: className,\n });\n\n return (\n \n {icon && (\n \n )}\n {children}\n {tooltip ? (\n \n {tooltip}\n \n ) : null}\n \n );\n};\n\nButtonNew.displayName = 'ButtonNew';\n\nButtonNew.propTypes = {\n children: defaultChildrenPropTypes,\n variant: PropTypes.oneOf(['default', 'primary', 'secondary']),\n rounded: PropTypes.bool,\n destructive: PropTypes.bool,\n type: PropTypes.oneOf(['button', 'submit']),\n className: PropTypes.string,\n tooltip: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),\n onKeyUp: PropTypes.func,\n icon: PropTypes.elementType,\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames/bind';\nimport { defaultChildrenPropTypes } from '../../common-prop-types/default-children-prop-types';\nimport { Icon } from '@crayons';\n\nexport const Link = (props) => {\n const {\n children,\n href = '#',\n variant = 'default',\n block,\n icon,\n rounded,\n className,\n ...otherProps\n } = props;\n\n const classes = classNames('c-link', {\n [`c-link--${variant}`]: variant && variant !== 'default',\n 'c-link--icon-left': icon && children,\n 'c-link--icon-alone': icon && !children,\n 'c-link--block': block,\n 'radius-full': rounded,\n [className]: className,\n });\n\n return (\n \n {icon && (\n \n )}\n {children}\n \n );\n};\n\nLink.displayName = 'Link';\n\nLink.propTypes = {\n variant: PropTypes.oneOf(['default', 'branded']),\n block: PropTypes.bool,\n rounded: PropTypes.bool,\n href: PropTypes.string.isRequired,\n className: PropTypes.string,\n children: defaultChildrenPropTypes,\n icon: PropTypes.elementType,\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames/bind';\nimport { defaultChildrenPropTypes } from '../../common-prop-types/default-children-prop-types';\nimport { Icon } from '@crayons';\n\nexport const CTA = (props) => {\n const {\n children,\n href = '#',\n variant = 'default',\n icon,\n className,\n ...otherProps\n } = props;\n\n const classes = classNames('c-cta', {\n [`c-cta--${variant}`]: variant && variant !== 'default',\n 'c-cta--icon-left': icon && children,\n [className]: className,\n });\n\n return (\n \n {icon && (\n \n )}\n {children}\n \n );\n};\n\nCTA.displayName = 'CTA';\n\nCTA.propTypes = {\n variant: PropTypes.oneOf(['default', 'branded']),\n rounded: PropTypes.bool,\n href: PropTypes.string.isRequired,\n className: PropTypes.string,\n children: defaultChildrenPropTypes.isRequired,\n icon: PropTypes.elementType,\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { defaultChildrenPropTypes } from '../../common-prop-types/default-children-prop-types';\n\n/**\n * Used to group related buttons together\n *\n * @param {string} labelText Used to form the aria-label providing to assistive technologies to describe the control\n * @param {HTMLElement[]} children The buttons rendered inside the group\n */\nexport const ButtonGroup = ({ children, labelText }) => (\n
\n {children}\n
\n);\n\nButtonGroup.displayName = 'ButtonGroup';\n\nButtonGroup.propTypes = {\n children: defaultChildrenPropTypes,\n labelText: PropTypes.string.isRequired,\n};\n","import { h } from 'preact';\nimport { useLayoutEffect, useState } from 'preact/hooks';\nimport PropTypes from 'prop-types';\nimport { defaultChildrenPropTypes } from '../../common-prop-types/default-children-prop-types';\nimport { initializeDropdown } from '@utilities/dropdownUtils';\n\n/**\n * A component to render a dropdown with the provided children.\n * This component handles the attachment of all open/close click events and listeners.\n *\n * @param {Object} props\n * @param {Array} props.children Children to be rendered inside the dropdown, passed via composition\n * @param {String} props.className Optional string of classnames to be applied to the dropdown (e.g for positioning)\n * @param {String} props.triggerButtonId The ID of the button element which should open and close the dropdown\n * @param {String} props.dropdownContentId The ID to be applied to the dropdown itself\n * @param {String} props.dropdownContentCloseButtonId An optional ID for any button inside the dropdown content itself which should close it\n * @param {Function} props.onOpen Optional callback for any side-effects needed when the dropdown opens\n * @param {Function} props.onClose Optional callback for any side-effects needed when the dropdown closes\n *\n * @example\n *
\n * \n * \n * {dropdownInnerContent}\n * \n *
\n */\nexport const Dropdown = ({\n children,\n className,\n triggerButtonId,\n dropdownContentId,\n dropdownContentCloseButtonId,\n onOpen = () => {},\n onClose = () => {},\n ...restOfProps\n}) => {\n const [isInitialized, setIsInitialized] = useState(false);\n useLayoutEffect(() => {\n if (!isInitialized) {\n initializeDropdown({\n triggerElementId: triggerButtonId,\n dropdownContentId,\n dropdownContentCloseButtonId,\n onOpen,\n onClose,\n });\n\n setIsInitialized(true);\n }\n }, [\n dropdownContentId,\n triggerButtonId,\n dropdownContentCloseButtonId,\n isInitialized,\n onOpen,\n onClose,\n ]);\n\n return (\n 0 ? ` ${className}` : ''\n }`}\n {...restOfProps}\n >\n {children}\n \n );\n};\n\nDropdown.defaultProps = {\n className: undefined,\n};\n\nDropdown.displayName = 'Dropdown';\n\nDropdown.propTypes = {\n children: defaultChildrenPropTypes.isRequired,\n className: PropTypes.string,\n triggerButtonId: PropTypes.string.isRequired,\n dropdownContentId: PropTypes.string.isRequired,\n dropdownContentCloseButtonId: PropTypes.string,\n onOpen: PropTypes.func,\n onClose: PropTypes.func,\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { defaultChildrenPropTypes } from '../../../common-prop-types';\n\n// Only radio and checkboxes require an additional CSS class (variant class). Other form elements do not.\n\nexport const FormField = ({ children, variant }) => {\n return (\n 0 ? ` crayons-field--${variant}` : ''\n }`}\n >\n {children}\n \n );\n};\n\nFormField.displayName = 'FormField';\n\nFormField.defaultProps = {\n variant: undefined,\n};\n\nFormField.propTypes = {\n children: defaultChildrenPropTypes.isRequired,\n variant: PropTypes.oneOf(['radio', 'checkbox']),\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\n\nexport const RadioButton = (props) => {\n const { id, value, name, className, checked, onClick, ...otherProps } = props;\n\n return (\n 0 ? ` ${className}` : ''\n }`}\n checked={checked}\n onClick={onClick}\n type=\"radio\"\n {...otherProps}\n />\n );\n};\n\nRadioButton.displayName = 'RadioButton';\n\nRadioButton.defaultProps = {\n id: undefined,\n className: undefined,\n checked: false,\n name: undefined,\n};\n\nRadioButton.propTypes = {\n id: PropTypes.string,\n value: PropTypes.string.isRequired,\n className: PropTypes.string,\n checked: PropTypes.bool,\n name: PropTypes.string,\n onClick: PropTypes.func.isRequired,\n};\n","import { h, Fragment } from 'preact';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { useState, useLayoutEffect } from 'preact/hooks';\nimport { HexColorPicker, HexColorInput } from 'react-colorful';\nimport { initializeDropdown } from '@utilities/dropdownUtils';\nimport { ButtonNew as Button } from '@crayons';\n\nconst convertThreeCharHexToSix = (hex) => {\n const r = hex.charAt(1);\n const g = hex.charAt(2);\n const b = hex.charAt(3);\n\n return `#${r}${r}${g}${g}${b}${b}`;\n};\n\nexport const ColorPicker = ({\n id,\n buttonLabelText,\n defaultValue,\n inputProps,\n onChange,\n onBlur,\n}) => {\n // Ternary has been used here to guard against an empty string being passed as default value\n const [color, setColor] = useState(defaultValue ? defaultValue : '#000');\n\n const buttonId = `color-popover-btn-${id}`;\n const popoverId = `color-popover-${id}`;\n\n useLayoutEffect(() => {\n initializeDropdown({\n triggerElementId: buttonId,\n dropdownContentId: popoverId,\n });\n }, [buttonId, popoverId]);\n\n // Hex codes may validly be represented by three characters, where r, g, b are all repeated,\n // e.g. #0D6 === #00DD66. To make sure that all color codes can be handled consistently through our app,\n // we convert any shorthand hex codes to their full 6 char representation.\n const handleBlur = () => {\n // Color always includes a leading '#', hence a length of 4\n if (color.length === 4) {\n const fullHexCode = convertThreeCharHexToSix(color);\n setColor(fullHexCode);\n onChange?.(fullHexCode);\n }\n };\n\n return (\n \n
\n \n {\n onChange?.(color);\n setColor(color);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n handleBlur();\n }}\n prefixed\n />\n \n {\n onChange?.(color);\n setColor(color);\n }}\n />\n
\n \n
\n );\n};\n\nColorPicker.propTypes = {\n id: PropTypes.string.isRequired,\n buttonLabelText: PropTypes.string.isRequired,\n defaultValue: PropTypes.string,\n inputProps: PropTypes.object,\n};\n","import { h } from 'preact';\n\nexport const Toggle = ({ ...otherProps }) => {\n return ;\n};\n\nToggle.displayName = 'Toggle';\n","export const MONTH_UNTIL_TODAY = 'MONTH_UNTIL_TODAY';\nexport const QUARTER_UNTIL_TODAY = 'QUARTER_UNTIL_TODAY';\nexport const YEAR_UNTIL_TODAY = 'YEAR_UNTIL_TODAY';\nexport const LAST_FULL_MONTH = 'LAST_FULL_MONTH';\nexport const LAST_FULL_QUARTER = 'LAST_FULL_QUARTER';\nexport const LAST_FULL_YEAR = 'LAST_FULL_YEAR';\n\nexport const ALL_PRESET_RANGES = [\n MONTH_UNTIL_TODAY,\n LAST_FULL_MONTH,\n QUARTER_UNTIL_TODAY,\n LAST_FULL_QUARTER,\n YEAR_UNTIL_TODAY,\n LAST_FULL_YEAR,\n];\n\nexport const RANGE_LABELS = {\n MONTH_UNTIL_TODAY: 'This month',\n QUARTER_UNTIL_TODAY: 'This quarter',\n YEAR_UNTIL_TODAY: 'This year',\n LAST_FULL_MONTH: 'Last month',\n LAST_FULL_QUARTER: 'Last quarter',\n LAST_FULL_YEAR: 'Last year',\n};\n\nconst PERIODS = {\n DAY: 'day',\n MONTH: 'month',\n QUARTER: 'quarter',\n YEAR: 'year',\n};\n\nconst getPeriodUntilToday = (today, period) => ({\n start: today.clone().startOf(period),\n end: today.clone(),\n});\n\nconst getLastFullPeriod = (today, period) => ({\n start: today.clone().subtract(1, period).startOf(period),\n end: today.clone().subtract(1, period).endOf(period),\n});\n\nexport const getDateRangeStartAndEndDates = ({ today, dateRangeName }) => {\n switch (dateRangeName) {\n case MONTH_UNTIL_TODAY:\n return getPeriodUntilToday(today, PERIODS.MONTH);\n case LAST_FULL_MONTH:\n return getLastFullPeriod(today, PERIODS.MONTH);\n case QUARTER_UNTIL_TODAY:\n return getPeriodUntilToday(today, PERIODS.QUARTER);\n case LAST_FULL_QUARTER:\n return getLastFullPeriod(today, PERIODS.QUARTER);\n case YEAR_UNTIL_TODAY:\n return getPeriodUntilToday(today, PERIODS.YEAR);\n case LAST_FULL_YEAR:\n return getLastFullPeriod(today, PERIODS.YEAR);\n }\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { useState, useLayoutEffect, useEffect } from 'preact/hooks';\nimport 'react-dates/initialize';\nimport moment from 'moment';\nimport { DateRangePicker as ReactDateRangePicker } from 'react-dates';\nimport defaultPhrases from 'react-dates/lib/defaultPhrases';\nimport {\n START_DATE,\n ICON_BEFORE_POSITION,\n VERTICAL_ORIENTATION,\n HORIZONTAL_ORIENTATION,\n} from 'react-dates/constants';\nimport { getDateRangeStartAndEndDates, RANGE_LABELS } from './dateRangeUtils';\nimport { Icon, ButtonNew as Button } from '@crayons';\nimport ChevronLeft from '@images/chevron-left.svg';\nimport ChevronRight from '@images/chevron-right.svg';\nimport Calendar from '@images/calendar.svg';\nimport { getCurrentLocale } from '@utilities/runtime';\nimport { useMediaQuery, BREAKPOINTS } from '@components/useMediaQuery';\n\nconst PICKER_PHRASES = {\n ...defaultPhrases,\n chooseAvailableStartDate: ({ date }) => `Choose ${date} as start date`,\n chooseAvailableEndDate: ({ date }) => `Choose ${date} as end date`,\n focusStartDate: 'Interact with the calendar and add your start date',\n invalidDateFormat: (format, errorPrefix) =>\n `${errorPrefix} must be in the format ${format}`,\n dateTooLate: (latestDate, errorPrefix) =>\n `${errorPrefix} must be on or before ${latestDate}`,\n dateTooEarly: (earliestDate, errorPrefix) =>\n `${errorPrefix} must be on or after ${earliestDate}`,\n};\n\nconst MONTH_NAMES = [...Array(12).keys()].map((key) =>\n new Date(0, key).toLocaleString('en', { month: 'long' }),\n);\n\nconst isDateOutsideOfRange = ({ date, minDate, maxDate }) =>\n !date.isBetween(minDate, maxDate);\n\n/**\n * Renders select elements allowing a user to jump to a given month/year\n * @param {Object} earliestMoment Moment object representing the earliest permitted date\n * @param {Object} latestMoment Moment object representing the latest permitted date\n * @param {Function} onMonthSelect Callback passed by react-dates library\n * @param {Function} onYearSelect Callback passed by react-dates library\n * @param {Object} month Moment object passed by react-dates library, representing the currently visible calendar\n */\nconst MonthYearPicker = ({\n earliestMoment,\n latestMoment,\n onMonthSelect,\n onYearSelect,\n month,\n}) => {\n const selectedMonth = month.month();\n const selectedYear = month.year();\n\n const latestYear = latestMoment.year();\n\n // Make sure we only display the available months for the currently selected year\n const latestMonthIndex =\n latestYear === selectedYear ? latestMoment.month() : 11;\n const availableMonths = MONTH_NAMES.slice(0, latestMonthIndex + 1);\n\n const yearsDiff = latestMoment.diff(earliestMoment, 'years');\n\n const years = [...Array(yearsDiff).keys()].map(\n (key) => latestMoment.year() - key,\n );\n years.push(earliestMoment.year());\n\n return (\n
\n onMonthSelect(month, e.target.value)}\n value={selectedMonth}\n >\n {availableMonths.map((month, index) => (\n \n ))}\n \n onYearSelect(month, e.target.value)}\n value={selectedYear}\n >\n {years.map((year) => (\n \n ))}\n \n
\n );\n};\n\n/**\n * Renders preset date ranges as 'quick select' buttons, if the range falls within the permitted dates.\n * Possible preset ranges are defined in ./dateRangeUtils.js\n *\n * @param {[string]} presetRanges The preset range names requested\n * @param {Object} earliestMoment Moment object representing earliest permitted date\n * @param {Object} latestMoment Moment object representing latest permitted date\n * @param {Function} onPresetSelected Callback which will receive start and end dates of selected preset\n * @param {Object} today Moment object representing today's date\n */\nconst PresetDateRangeOptions = ({\n presetRanges = [],\n earliestMoment,\n latestMoment,\n onPresetSelected,\n today,\n}) => {\n // Filter out any requested ranges which extend beyond the valid time period\n const presetsWithinPermittedDates = presetRanges.filter((dateRangeName) => {\n const { start: rangeStart, end: rangeEnd } = getDateRangeStartAndEndDates({\n today,\n dateRangeName,\n });\n\n return (\n rangeStart.isSameOrBefore(rangeEnd) &&\n rangeStart.isSameOrAfter(earliestMoment) &&\n rangeEnd.isSameOrBefore(latestMoment)\n );\n });\n\n if (presetsWithinPermittedDates.length === 0) {\n return null;\n }\n\n return (\n
    \n {presetsWithinPermittedDates.map((rangeName) => (\n
  • \n {\n onPresetSelected(\n getDateRangeStartAndEndDates({\n today,\n dateRangeName: rangeName,\n }),\n );\n }}\n >\n {RANGE_LABELS[rangeName]}\n \n
  • \n ))}\n
\n );\n};\n\n/**\n * Hook that will attach listeners to date range inputs and return the correct error message for each.\n * @param {Object} props\n * @param {Object} props.earliesMoment Moment object reflecting the earliest date that may be selected\n * @param {Object} props.latestMoment Moment object reflecting the latest date that may be selected\n * @param {string} props.dateFormat The expected date format, e.g. \"MM/DD/YYYY\"\n */\nconst useDateRangeValidation = ({\n earliestMoment,\n latestMoment,\n dateFormat,\n}) => {\n const [startDateInput, setStartDateInput] = useState(null);\n const [endDateInput, setEndDateInput] = useState(null);\n const [startDateError, setStartDateError] = useState('');\n const [endDateError, setEndDateError] = useState('');\n\n useEffect(() => {\n const setError = (error, inputType) =>\n inputType === 'start'\n ? setStartDateError(error ?? '')\n : setEndDateError(error ?? '');\n\n const handleBlur = ({ target: { value } }, inputType) => {\n if (value === '') {\n setError('', inputType);\n return;\n }\n\n const errorPrefix = `${inputType === 'start' ? 'Start' : 'End'} date`;\n\n const valueMoment = moment(value, dateFormat);\n if (!valueMoment.isValid()) {\n setError(\n PICKER_PHRASES.invalidDateFormat(dateFormat, errorPrefix),\n inputType,\n );\n return;\n }\n\n if (valueMoment.isBefore(earliestMoment)) {\n setError(\n PICKER_PHRASES.dateTooEarly(\n earliestMoment.format(dateFormat),\n errorPrefix,\n ),\n inputType,\n );\n return;\n }\n\n if (valueMoment.isAfter(latestMoment)) {\n setError(\n PICKER_PHRASES.dateTooLate(\n latestMoment.format(dateFormat),\n errorPrefix,\n ),\n inputType,\n );\n return;\n }\n\n // Date is valid\n setError('', inputType);\n };\n\n const handleStartBlur = (e) => handleBlur(e, 'start');\n const handleEndBlur = (e) => handleBlur(e, 'end');\n\n startDateInput?.addEventListener('blur', handleStartBlur);\n endDateInput?.addEventListener('blur', handleEndBlur);\n\n return () => {\n startDateInput?.removeEventListener('blur', handleStartBlur);\n endDateInput?.removeEventListener('blur', handleEndBlur);\n };\n }, [startDateInput, endDateInput, dateFormat, earliestMoment, latestMoment]);\n\n return { setStartDateInput, setEndDateInput, startDateError, endDateError };\n};\n\n/**\n * Used to facilitate picking a date range. This component is a wrapper around the one provided from react-dates.\n *\n * @param {Object} props\n * @param {string} props.startDateId A unique ID for the start date input\n * @param {string} props.endDateId A unique ID for the end date input\n * @param {Date} props.defaultStartDate The optional initial value for the start date\n * @param {Date} props.defaultEndDate The optional initial value for the end date\n * @param {Date} props.maxEndDate The latest date that may be selected\n * @param {Date} props.minStartDate The oldest date that may be selected\n * @param {Function} props.onDatesChanged Callback function for when dates are selected. Receives an object with startDate and endDate values.\n * @param {[string]} props.presetRanges Quick-select preset date ranges to offer in the calendar. These will only be shown if they fall within the min and max dates.\n * @param {string} props.startDateAriaLabel Custom aria-label for start date input\n * @param {string} props.endDateAriaLabel Custom aria-label for end date input\n * @param {Date} props.todaysDate Optional param to pass in today's Date, primarily for testing purposes\n */\nexport const DateRangePicker = ({\n startDateId,\n endDateId,\n defaultStartDate,\n defaultEndDate,\n maxEndDate = new Date(),\n minStartDate = new Date(),\n onDatesChanged,\n presetRanges = [],\n startDateAriaLabel,\n endDateAriaLabel,\n todaysDate = new Date(),\n}) => {\n const [focusedInput, setFocusedInput] = useState(START_DATE);\n const [startMoment, setStartMoment] = useState(\n defaultStartDate ? moment(defaultStartDate) : null,\n );\n\n const [endMoment, setEndMoment] = useState(\n defaultEndDate ? moment(defaultEndDate) : null,\n );\n\n const dateFormat =\n getCurrentLocale().toLowerCase() === 'en-us' ? 'MM/DD/YYYY' : 'DD/MM/YYYY';\n\n const useCompactLayout = useMediaQuery(\n `(max-width: ${BREAKPOINTS.Medium - 1}px)`,\n );\n\n const earliestMoment = moment(minStartDate).startOf('day');\n const latestMoment = moment(maxEndDate).endOf('day');\n\n const isMonthSameAsLatestMonth = (relevantDate) =>\n relevantDate.year() === latestMoment.year() &&\n relevantDate.month() === latestMoment.month();\n\n const today = moment(todaysDate);\n\n const { setStartDateInput, setEndDateInput, startDateError, endDateError } =\n useDateRangeValidation({ earliestMoment, latestMoment, dateFormat });\n\n useLayoutEffect(() => {\n const startDateInput = document.getElementById(startDateId);\n startDateInput.setAttribute('aria-describedby', 'start-date-error');\n setStartDateInput(startDateInput);\n\n const endDateInput = document.getElementById(endDateId);\n endDateInput.setAttribute('aria-describedby', 'end-date-error');\n setEndDateInput(endDateInput);\n }, [startDateId, endDateId, setStartDateInput, setEndDateInput]);\n\n return (\n // We wrap in a span to assist with scoping CSS selectors & overriding styles from react-dates\n \n }\n navNext={}\n minDate={earliestMoment}\n maxDate={latestMoment}\n initialVisibleMonth={() => {\n const relevantDate = startMoment ? startMoment : today;\n\n return isMonthSameAsLatestMonth(relevantDate)\n ? relevantDate.clone().subtract(1, 'month')\n : relevantDate;\n }}\n customInputIcon={}\n showDefaultInputIcon={!(startMoment || endMoment)}\n inputIconPosition={ICON_BEFORE_POSITION}\n orientation={\n useCompactLayout ? VERTICAL_ORIENTATION : HORIZONTAL_ORIENTATION\n }\n showClearDates={startMoment || endMoment}\n customArrowIcon=\"-\"\n phrases={PICKER_PHRASES}\n onFocusChange={(focusedInput) => setFocusedInput(focusedInput)}\n isOutsideRange={(date) =>\n isDateOutsideOfRange({\n date,\n minDate: earliestMoment,\n maxDate: latestMoment,\n })\n }\n onDatesChange={({ startDate, endDate }) => {\n setStartMoment(startDate);\n setEndMoment(endDate);\n onDatesChanged?.({\n startDate: startDate?.toDate(),\n endDate: endDate?.toDate(),\n });\n }}\n small={useCompactLayout}\n renderMonthElement={(props) => (\n \n )}\n renderCalendarInfo={() => (\n {\n setStartMoment(start);\n setEndMoment(end);\n // Force the calendar to close, same as if user clicks an end date manually\n setFocusedInput(false);\n }}\n />\n )}\n />\n {/* This hidden input provides information that may be needed by implementing forms to properly parse dates */}\n \n \n
{startDateError}
\n
{endDateError}
\n \n \n );\n};\n\nDateRangePicker.propTypes = {\n startDateId: PropTypes.string.isRequired,\n endDateId: PropTypes.string.isRequired,\n defaultStartDate: PropTypes.instanceOf(Date),\n defaultEndDate: PropTypes.instanceOf(Date),\n maxStartDate: PropTypes.instanceOf(Date),\n maxEndDate: PropTypes.instanceOf(Date),\n onDatesChanged: PropTypes.func,\n presetRanges: PropTypes.arrayOf(PropTypes.string),\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames/bind';\n\nexport const Icon = ({\n src: InternalIcon,\n native,\n className,\n ...otherProps\n}) => {\n return (\n \n );\n};\n\nIcon.displayName = 'Icon';\n\nIcon.propTypes = {\n native: PropTypes.bool,\n className: PropTypes.string,\n src: PropTypes.elementType.isRequired,\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { defaultChildrenPropTypes } from '../../common-prop-types';\nimport { FocusTrap } from '../../shared/components/focusTrap';\n\n/**\n * A component that creates a full-width modal that slides in from the bottom of viewport.\n *\n *\n * @param {object} props\n * @param {Array} props.children\n * @param {string} props.title The title to be applied to the dialog, surfaced to screen reader users\n * @param {Function} props.onClose Action to complete when user opts to close the drawer\n *\n * @example\n * const [isDrawerOpen, setIsDrawerOpen] = useState(false);\n * return (\n *
\n * \n * {isDrawerOpen && (\n * setIsDrawerOpen(false)}\n * >\n *

Lorem ipsum

\n * \n * \n * )}\n *
\n * );\n */\nexport const MobileDrawer = ({ children, title, onClose = () => {} }) => {\n return (\n
\n
\n \n \n {children}\n
\n \n
\n );\n};\n\nMobileDrawer.propTypes = {\n children: defaultChildrenPropTypes.isRequired,\n title: PropTypes.string.isRequired,\n onClose: PropTypes.func,\n};\n","import { h } from 'preact';\nimport {\n getLastIndexOfCharacter,\n getNextIndexOfCharacter,\n getNumberOfNewLinesFollowingSelection,\n getNumberOfNewLinesPrecedingSelection,\n getSelectionData,\n} from '../../utilities/textAreaUtils';\nimport { getOSKeyboardModifierKeyString } from '@utilities/runtime';\nimport BoldIcon from '@images/bold.svg';\nimport ItalicIcon from '@images/italic.svg';\nimport LinkIcon from '@images/link.svg';\nimport OrderedListIcon from '@images/list-ordered.svg';\nimport UnorderedListIcon from '@images/list-unordered.svg';\nimport HeadingIcon from '@images/heading.svg';\nimport QuoteIcon from '@images/quote.svg';\nimport CodeIcon from '@images/code.svg';\nimport CodeBlockIcon from '@images/codeblock.svg';\nimport EmbedIcon from '@images/lightning.svg';\nimport UnderlineIcon from '@images/underline.svg';\nimport StrikethroughIcon from '@images/strikethrough.svg';\nimport DividerIcon from '@images/divider.svg';\nimport { Icon } from '@crayons';\n\nconst ORDERED_LIST_ITEM_REGEX = /^\\d+\\.\\s+.*/;\nconst MARKDOWN_LINK_REGEX =\n /^\\[([\\w\\s\\d]*)\\]\\((url|(https?:\\/\\/[\\w\\d./?=#]+))\\)$/;\nconst URL_PLACEHOLDER_TEXT = 'url';\n\nconst NUMBER_OF_NEW_LINES_BEFORE_BLOCK_SYNTAX = 2;\nconst NUMBER_OF_NEW_LINES_BEFORE_AFTER_SYNTAX = 1;\n\nconst getNewLinePrefixSuffixes = ({ selectionStart, selectionEnd, value }) => {\n const numberOfNewLinesBeforeSelection = getNumberOfNewLinesPrecedingSelection(\n { selectionStart, value },\n );\n const numberOfNewLinesFollowingSelection =\n getNumberOfNewLinesFollowingSelection({ selectionEnd, value });\n\n // We only add new lines if we're not at the beginning of the text area\n const numberOfNewLinesNeededAtStart =\n selectionStart === 0\n ? 0\n : NUMBER_OF_NEW_LINES_BEFORE_BLOCK_SYNTAX -\n numberOfNewLinesBeforeSelection;\n\n const newLinesPrefix = String.prototype.padStart(\n numberOfNewLinesNeededAtStart,\n '\\n',\n );\n\n const newLinesSuffix =\n numberOfNewLinesFollowingSelection >=\n NUMBER_OF_NEW_LINES_BEFORE_AFTER_SYNTAX\n ? ''\n : '\\n';\n\n return { newLinesPrefix, newLinesSuffix };\n};\n\nconst handleLinkFormattingForEmptyTextSelection = ({\n textBeforeSelection,\n textAfterSelection,\n value,\n selectionStart,\n selectionEnd,\n}) => {\n const basicFormattingForEmptySelection = {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: `[](${URL_PLACEHOLDER_TEXT})`,\n newCursorStart: selectionStart + 3,\n newCursorEnd: selectionEnd + 6,\n };\n\n // Directly after inserting a link with a URL highlighted, cursor is inside the link description '[]'\n // Check if we are inside empty link description remove the link syntax if so\n const directlySurroundedByLinkStructure =\n textBeforeSelection.slice(-1) === '[' &&\n textAfterSelection.slice(0, 2) === '](';\n\n if (!directlySurroundedByLinkStructure)\n return basicFormattingForEmptySelection;\n\n // Search for the closing bracket of markdown link\n const indexOfLinkStructureEnd = getNextIndexOfCharacter({\n content: value,\n selectionIndex: selectionStart,\n character: ')',\n breakOnCharacters: [' ', '\\n'],\n });\n\n if (indexOfLinkStructureEnd === -1) return basicFormattingForEmptySelection;\n\n // Remove the markdown link structure, preserving the link text if it isn't the \"url\" placeholder\n const urlText = value.slice(selectionEnd + 2, indexOfLinkStructureEnd);\n\n return {\n editSelectionStart: selectionStart - 1,\n editSelectionEnd: indexOfLinkStructureEnd + 1,\n replaceSelectionWith: urlText === URL_PLACEHOLDER_TEXT ? '' : urlText,\n newCursorStart: selectionStart - 1,\n newCursorEnd: selectionEnd - 1,\n };\n};\n\nconst handleLinkFormattingForUrlSelection = ({\n textBeforeSelection,\n textAfterSelection,\n value,\n selectionStart,\n selectionEnd,\n selectedText,\n}) => {\n const basicFormattingForLinkSelection = {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: `[](${selectedText})`,\n newCursorStart: selectionStart + 1,\n newCursorEnd: selectionStart + 1,\n };\n\n // Check if the text selection is likely inside a currently formatted markdown link\n const directlySurroundedByLinkStructure =\n textBeforeSelection.slice(-2) === '](' &&\n textAfterSelection.slice(0, 1) === ')';\n\n if (!directlySurroundedByLinkStructure)\n return basicFormattingForLinkSelection;\n\n // Get the index of where the current link opens so we can get the text inside the square brackets\n const indexOfSyntaxOpen = getLastIndexOfCharacter({\n content: value,\n selectionIndex: selectionStart,\n character: '[',\n });\n\n // If link syntax is incomplete, format the selection as a link\n if (indexOfSyntaxOpen === -1) return basicFormattingForLinkSelection;\n\n // Replace the markdown with the link text in square brackets, if available\n let textToReplaceMarkdown = textBeforeSelection.slice(\n indexOfSyntaxOpen + 1,\n -2,\n );\n\n // If not available, take the URL as long as it's not the placeholder 'url' text\n if (textToReplaceMarkdown === '') {\n textToReplaceMarkdown =\n selectedText === URL_PLACEHOLDER_TEXT ? '' : selectedText;\n }\n\n return {\n editSelectionStart: indexOfSyntaxOpen,\n editSelectionEnd: selectionEnd + 1,\n replaceSelectionWith: textToReplaceMarkdown,\n newCursorStart: indexOfSyntaxOpen,\n newCursorEnd: indexOfSyntaxOpen + textToReplaceMarkdown.length,\n };\n};\n\nconst handleUndoMarkdownLinkSelection = ({\n selectedText,\n selectionStart,\n selectionEnd,\n}) => {\n const linkDescriptionEnd = getNextIndexOfCharacter({\n content: selectedText,\n selectionIndex: 0,\n character: ']',\n });\n\n let textToReplaceMarkdown = selectedText.slice(1, linkDescriptionEnd);\n\n // Keep the URL instead if no link description exists\n if (textToReplaceMarkdown === '') {\n const linkText = selectedText.slice(linkDescriptionEnd + 2, -1);\n textToReplaceMarkdown = linkText === URL_PLACEHOLDER_TEXT ? '' : linkText;\n }\n\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: textToReplaceMarkdown,\n newCursorStart: selectionStart,\n newCursorEnd: selectionStart + textToReplaceMarkdown.length,\n };\n};\n\nconst isStringStartAUrl = (string) => {\n const startingText = string.substring(0, 8);\n return startingText === 'https://' || startingText.startsWith('http://');\n};\n\nconst undoOrAddFormattingForInlineSyntax = ({\n value,\n selectionStart,\n selectionEnd,\n prefix,\n suffix,\n}) => {\n const { length: prefixLength } = prefix;\n const { length: suffixLength } = suffix;\n const { selectedText, textBeforeSelection, textAfterSelection } =\n getSelectionData({ selectionStart, selectionEnd, value });\n\n // Check if selected text has prefix/suffix\n const selectedTextAlreadyFormatted =\n selectedText.slice(0, prefixLength) === prefix &&\n selectedText.slice(-1 * suffixLength) === suffix;\n\n if (selectedTextAlreadyFormatted) {\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: selectedText.slice(prefixLength, -1 * suffixLength),\n newCursorStart: selectionStart,\n newCursorEnd: selectionEnd - (prefixLength + suffixLength),\n };\n }\n\n // Check if immediate surrounding content has prefix/suffix\n const surroundingTextHasFormatting =\n textBeforeSelection.substring(textBeforeSelection.length - prefixLength) ===\n prefix && textAfterSelection.substring(0, suffixLength) === suffix;\n\n if (surroundingTextHasFormatting) {\n return {\n editSelectionStart: selectionStart - prefixLength,\n editSelectionEnd: selectionEnd + suffixLength,\n replaceSelectionWith: selectedText,\n newCursorStart: selectionStart - prefixLength,\n newCursorEnd: selectionEnd - prefixLength,\n };\n }\n\n // No formatting to undo - format the selected text\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: `${prefix}${selectedText}${suffix}`,\n newCursorStart: selectionStart + prefixLength,\n newCursorEnd: selectionEnd + prefixLength,\n };\n};\n\nconst undoOrAddFormattingForMultilineSyntax = ({\n selectionStart,\n selectionEnd,\n value,\n linePrefix,\n blockPrefix,\n blockSuffix,\n}) => {\n const { selectedText, textBeforeSelection, textAfterSelection } =\n getSelectionData({ selectionStart, selectionEnd, value });\n\n let formattedText = selectedText;\n\n if (linePrefix) {\n const { length: prefixLength } = linePrefix;\n\n // If no selection, check if we're in a freshly inserted syntax\n if (selectedText === '') {\n const lastNewLine =\n textBeforeSelection === ''\n ? -1\n : getLastIndexOfCharacter({\n content: value,\n selectionIndex: selectionStart - 1,\n character: '\\n',\n });\n\n const lineStart = lastNewLine === -1 ? 0 : lastNewLine + 1;\n\n if (\n textBeforeSelection.slice(lineStart, lineStart + prefixLength) ===\n linePrefix\n ) {\n // Remove the list formatting\n\n return {\n editSelectionStart: lineStart,\n editSelectionEnd: lineStart + prefixLength,\n replaceSelectionWith: '',\n newCursorStart: selectionStart - prefixLength,\n newCursorEnd: selectionEnd - prefixLength,\n };\n }\n }\n\n // Split by new lines and check each line has formatting\n const splitByNewLine = selectedText\n .split('\\n')\n .filter((line) => line !== '');\n\n const isAlreadyFormatted =\n splitByNewLine.length > 0 &&\n splitByNewLine.every(\n (line) => line.slice(0, prefixLength) === linePrefix,\n );\n\n if (isAlreadyFormatted) {\n // Remove the formatting\n const unformattedText = splitByNewLine\n .map((line) => line.slice(prefixLength))\n .join('\\n');\n\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: unformattedText,\n newCursorStart: selectionStart,\n newCursorEnd:\n selectionEnd + (unformattedText.length - selectedText.length),\n };\n }\n\n // Otherwise add the prefix to each line to create the new formatted text\n formattedText =\n selectedText === ''\n ? linePrefix\n : splitByNewLine.map((line) => `${linePrefix}${line}`).join('\\n');\n } else {\n // Uses only block prefix and suffix\n const { length: prefixLength } = blockPrefix;\n const { length: suffixLength } = blockSuffix;\n\n // does the selection start and end with the prefix/suffix\n const selectionIsFormatted =\n selectedText.slice(0, prefixLength) === blockPrefix &&\n selectedText.slice(-1 * suffixLength) === blockSuffix;\n\n if (selectionIsFormatted) {\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: selectedText.slice(\n prefixLength,\n -1 * suffixLength,\n ),\n newCursorStart: selectionStart,\n newCursorEnd: selectionEnd - prefixLength - suffixLength,\n };\n }\n\n // or does the prefix/suffix plus new line chars immediately precede and follow the selection\n const surroundingTextIsFormatted =\n textBeforeSelection.slice(-1 * prefixLength) === blockPrefix &&\n textAfterSelection.slice(0, suffixLength) === blockSuffix;\n\n if (surroundingTextIsFormatted) {\n return {\n editSelectionStart: selectionStart - prefixLength,\n editSelectionEnd: selectionEnd + suffixLength,\n replaceSelectionWith: selectedText,\n newCursorStart: selectionStart - prefixLength,\n newCursorEnd: selectionEnd - prefixLength,\n };\n }\n }\n\n // Add the formatting\n\n const { newLinesPrefix, newLinesSuffix } = getNewLinePrefixSuffixes({\n selectionStart,\n selectionEnd,\n value,\n });\n const { length: newLinePrefixLength } = newLinesPrefix;\n\n const cursorStartBaseline = selectionStart + newLinePrefixLength;\n const cursorStartBlockPrefixOffset = blockPrefix ? blockPrefix.length : 0;\n const cursorStartLinePrefixOffset =\n selectedText === '' && linePrefix ? linePrefix.length : 0;\n\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: `${newLinesPrefix}${\n blockPrefix ? blockPrefix : ''\n }${formattedText}${blockSuffix ? blockSuffix : ''}${newLinesSuffix}`,\n newCursorStart:\n cursorStartBaseline +\n cursorStartBlockPrefixOffset +\n cursorStartLinePrefixOffset,\n newCursorEnd:\n selectionEnd +\n formattedText.length -\n selectedText.length +\n newLinePrefixLength +\n (blockPrefix?.length || 0),\n };\n};\n\nexport const getNewTextAreaValueWithEdits = ({\n textAreaValue,\n editSelectionStart,\n editSelectionEnd,\n replaceSelectionWith,\n}) =>\n `${textAreaValue.substring(\n 0,\n editSelectionStart,\n )}${replaceSelectionWith}${textAreaValue.substring(editSelectionEnd)}`;\n\nexport const markdownSyntaxFormatters = {\n bold: {\n icon: () => ,\n label: 'Bold',\n getKeyboardShortcut: () => {\n const modifier = getOSKeyboardModifierKeyString();\n return {\n command: `${modifier}+b`,\n tooltipHint: `${modifier.toUpperCase()} + B`,\n };\n },\n getFormatting: ({ selectionStart, selectionEnd, value }) => {\n return undoOrAddFormattingForInlineSyntax({\n selectionStart,\n selectionEnd,\n value,\n prefix: '**',\n suffix: '**',\n });\n },\n },\n italic: {\n icon: () => ,\n label: 'Italic',\n getKeyboardShortcut: () => {\n const modifier = getOSKeyboardModifierKeyString();\n return {\n command: `${modifier}+i`,\n tooltipHint: `${modifier.toUpperCase()} + I`,\n };\n },\n getFormatting: ({ selectionStart, selectionEnd, value }) => {\n return undoOrAddFormattingForInlineSyntax({\n selectionStart,\n selectionEnd,\n value,\n prefix: '_',\n suffix: '_',\n });\n },\n },\n link: {\n icon: () => ,\n label: 'Link',\n getKeyboardShortcut: () => {\n const modifier = getOSKeyboardModifierKeyString();\n return {\n command: `${modifier}+k`,\n tooltipHint: `${modifier.toUpperCase()} + K`,\n };\n },\n getFormatting: ({ selectionStart, selectionEnd, value }) => {\n const { selectedText, textBeforeSelection, textAfterSelection } =\n getSelectionData({ selectionStart, selectionEnd, value });\n\n if (selectedText === '') {\n return handleLinkFormattingForEmptyTextSelection({\n textBeforeSelection,\n textAfterSelection,\n value,\n selectionStart,\n selectionEnd,\n });\n }\n\n if (\n isStringStartAUrl(selectedText) ||\n selectedText === URL_PLACEHOLDER_TEXT\n ) {\n return handleLinkFormattingForUrlSelection({\n textBeforeSelection,\n textAfterSelection,\n value,\n selectionStart,\n selectedText,\n selectionEnd,\n });\n }\n\n // If the whole selectedText matches markdown link formatting, undo it\n if (selectedText.match(MARKDOWN_LINK_REGEX)) {\n return handleUndoMarkdownLinkSelection({\n selectedText,\n selectionStart,\n selectionEnd,\n textBeforeSelection,\n textAfterSelection,\n });\n }\n\n // Finally, handle the case where link syntax is inserted for a selection other than a URL\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: `[${selectedText}](${URL_PLACEHOLDER_TEXT})`,\n newCursorStart: selectionStart + selectedText.length + 3,\n newCursorEnd: selectionEnd + 6,\n };\n },\n },\n orderedList: {\n icon: () => ,\n label: 'Ordered list',\n getFormatting: ({ selectionStart, selectionEnd, value }) => {\n const { selectedText, textBeforeSelection } = getSelectionData({\n selectionStart,\n selectionEnd,\n value,\n });\n\n const { newLinesPrefix, newLinesSuffix } = getNewLinePrefixSuffixes({\n selectionStart,\n selectionEnd,\n value,\n });\n const { length: newLinePrefixLength } = newLinesPrefix;\n const { length: newLineSuffixLength } = newLinesSuffix;\n\n if (selectedText === '') {\n // Check start of line for whether we're in an empty ordered list\n const lastNewLine =\n textBeforeSelection === ''\n ? -1\n : getLastIndexOfCharacter({\n content: value,\n selectionIndex: selectionStart - 1,\n character: '\\n',\n });\n\n const lineStart = lastNewLine === -1 ? 0 : lastNewLine + 1;\n\n if (textBeforeSelection.slice(lineStart, lineStart + 3) === '1. ') {\n // Remove the list formatting\n return {\n editSelectionStart: lineStart,\n editSelectionEnd: lineStart + 3,\n replaceSelectionWith: '',\n newCursorStart: selectionStart - 3,\n newCursorEnd: selectionEnd - 3,\n };\n }\n }\n\n if (selectedText === '') {\n // Otherwise insert an empty list for an empty selection\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: `${newLinesPrefix}1. ${newLinesSuffix}`,\n newCursorStart: selectionStart + 3 + newLinePrefixLength,\n newCursorEnd: selectionEnd + 3 + newLinePrefixLength,\n };\n }\n\n const splitByNewLine = selectedText.split('\\n');\n\n const isAlreadyAnOrderedList = splitByNewLine.every(\n (line) => line.match(ORDERED_LIST_ITEM_REGEX) || line === '',\n );\n\n if (isAlreadyAnOrderedList) {\n // Undo formatting\n const newText = splitByNewLine\n .filter((line) => line !== '')\n .map((line) => {\n const indexOfFullStop = line.indexOf('.');\n return line.substring(indexOfFullStop + 2);\n })\n .join('\\n');\n\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: newText,\n newCursorStart: selectionStart + selectedText.indexOf('.') - 1,\n newCursorEnd: selectionEnd + newText.length - selectedText.length,\n };\n }\n // Otherwise convert to an ordered list\n const formattedList = `${newLinesPrefix}${splitByNewLine\n .map((textChunk, index) => `${index + 1}. ${textChunk}`)\n .join('\\n')}${newLinesSuffix}`;\n\n const cursorOffsetStart =\n selectedText.length === 0 ? 4 : newLinePrefixLength;\n\n return {\n editSelectionStart: selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: formattedList,\n newCursorStart: selectionStart + cursorOffsetStart,\n newCursorEnd:\n selectionStart + formattedList.length - newLineSuffixLength,\n };\n },\n },\n unorderedList: {\n icon: () => ,\n label: 'Unordered list',\n getFormatting: ({ selectionStart, selectionEnd, value }) => {\n return undoOrAddFormattingForMultilineSyntax({\n selectionStart,\n selectionEnd,\n value,\n linePrefix: '- ',\n });\n },\n },\n heading: {\n icon: () => ,\n label: 'Heading',\n getFormatting: ({ selectionStart, selectionEnd, value }) => {\n let currentLineSelectionStart = selectionStart;\n\n // The 'heading' formatter changes insertion based on the existing heading level of the current line\n // So we find the start of the current line and check for '#' characters\n if (selectionStart > 0) {\n const lastNewLine = getLastIndexOfCharacter({\n content: value,\n selectionIndex: selectionStart - 1,\n character: '\\n',\n });\n\n const indexOfFirstLineCharacter =\n lastNewLine === -1 ? 0 : lastNewLine + 1;\n\n if (value.charAt(indexOfFirstLineCharacter) === '#') {\n currentLineSelectionStart = indexOfFirstLineCharacter;\n }\n }\n\n const { selectedText } = getSelectionData({\n selectionStart: currentLineSelectionStart,\n selectionEnd,\n value,\n });\n\n let currentHeadingIndex = 0;\n while (selectedText.charAt(currentHeadingIndex) === '#') {\n currentHeadingIndex++;\n }\n\n // After h4, revert to no heading at all\n if (currentHeadingIndex >= 4) {\n return {\n editSelectionStart: currentLineSelectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: selectedText.substring(5),\n newCursorStart: selectionStart - 5,\n newCursorEnd: selectionEnd - 5,\n };\n }\n\n const { newLinesPrefix, newLinesSuffix } = getNewLinePrefixSuffixes({\n selectionStart,\n selectionEnd,\n value,\n });\n const { length: newLinePrefixLength } = newLinesPrefix;\n\n const adjustingHeading = currentHeadingIndex > 0;\n const cursorOffset = adjustingHeading ? 1 : 3 + newLinePrefixLength;\n\n return {\n editSelectionStart: adjustingHeading\n ? currentLineSelectionStart\n : selectionStart,\n editSelectionEnd: selectionEnd,\n replaceSelectionWith: adjustingHeading\n ? `#${selectedText}`\n : `${newLinesPrefix}## ${selectedText}${newLinesSuffix}`,\n newCursorStart: selectionStart + cursorOffset,\n newCursorEnd: selectionEnd + cursorOffset,\n };\n },\n },\n quote: {\n icon: () => ,\n label: 'Quote',\n getFormatting: ({ selectionStart, selectionEnd, value }) =>\n undoOrAddFormattingForMultilineSyntax({\n selectionStart,\n selectionEnd,\n value,\n linePrefix: '> ',\n }),\n },\n code: {\n icon: () => ,\n label: 'Code',\n getFormatting: ({ selectionStart, selectionEnd, value }) =>\n undoOrAddFormattingForInlineSyntax({\n selectionStart,\n selectionEnd,\n value,\n prefix: '`',\n suffix: '`',\n }),\n },\n codeBlock: {\n icon: () => ,\n label: 'Code block',\n getFormatting: ({ selectionStart, selectionEnd, value }) =>\n undoOrAddFormattingForMultilineSyntax({\n selectionStart,\n selectionEnd,\n value,\n blockPrefix: '```\\n',\n blockSuffix: '\\n```',\n }),\n },\n embed: {\n icon: () => ,\n label: 'Embed',\n getKeyboardShortcut: () => {\n const modifier = getOSKeyboardModifierKeyString();\n return {\n command: `${modifier}+shift+k`,\n tooltipHint: `${modifier.toUpperCase()} + SHIFT + K`,\n };\n },\n getFormatting: ({ selectionStart, selectionEnd, value }) =>\n undoOrAddFormattingForInlineSyntax({\n value,\n selectionStart,\n selectionEnd,\n prefix: '{% embed ',\n suffix: ' %}',\n }),\n },\n underline: {\n icon: () => ,\n label: 'Underline',\n getKeyboardShortcut: () => {\n const modifier = getOSKeyboardModifierKeyString();\n return {\n command: `${modifier}+u`,\n tooltipHint: `${modifier.toUpperCase()} + U`,\n };\n },\n getFormatting: ({ selectionStart, selectionEnd, value }) =>\n undoOrAddFormattingForInlineSyntax({\n selectionStart,\n selectionEnd,\n value,\n prefix: '',\n suffix: '',\n }),\n },\n strikethrough: {\n icon: () => ,\n label: 'Strikethrough',\n getKeyboardShortcut: () => {\n const modifier = getOSKeyboardModifierKeyString();\n return {\n command: `${modifier}+shift+x`,\n tooltipHint: `${modifier.toUpperCase()} + SHIFT + X`,\n };\n },\n getFormatting: ({ selectionStart, selectionEnd, value }) =>\n undoOrAddFormattingForInlineSyntax({\n selectionStart,\n selectionEnd,\n value,\n prefix: '~~',\n suffix: '~~',\n }),\n },\n divider: {\n icon: () => ,\n label: 'Line divider',\n getFormatting: ({ selectionStart, selectionEnd, value }) =>\n undoOrAddFormattingForMultilineSyntax({\n selectionStart,\n selectionEnd,\n value,\n blockPrefix: '---\\n',\n blockSuffix: '',\n }),\n },\n};\n","import { h, cloneElement } from 'preact';\nimport { useState, useLayoutEffect, useRef } from 'preact/hooks';\nimport { ImageUploader } from '../../article-form/components/ImageUploader';\nimport {\n markdownSyntaxFormatters,\n getNewTextAreaValueWithEdits,\n} from './markdownSyntaxFormatters';\nimport OverflowIcon from '@images/overflow-vertical.svg';\nimport { ButtonNew as Button } from '@crayons';\nimport { useKeyboardShortcuts } from '@components/useKeyboardShortcuts';\nimport { BREAKPOINTS, useMediaQuery } from '@components/useMediaQuery';\nimport { getSelectionData } from '@utilities/textAreaUtils';\n\n// Placeholder text displayed while an image is uploading\nconst UPLOADING_IMAGE_PLACEHOLDER = '![Uploading image](...)';\n\nconst MAX_CORE_FORMATTERS_BY_SCREEN_SIZE = {\n small: 5,\n large: 7,\n extraLarge: 10,\n};\n\nconst getNumberOfIconsToDisplayInToolbar = ({\n isSmallScreen,\n isLargeScreen,\n}) => {\n if (isSmallScreen) {\n return MAX_CORE_FORMATTERS_BY_SCREEN_SIZE.small;\n }\n if (isLargeScreen) {\n return MAX_CORE_FORMATTERS_BY_SCREEN_SIZE.large;\n }\n return MAX_CORE_FORMATTERS_BY_SCREEN_SIZE.extraLarge;\n};\n\n/**\n * Returns the next sibling in the DOM which matches the given CSS selector.\n * This makes sure that only toolbar buttons are cycled through on Arrow key press,\n * and not e.g. the hidden file input from ImageUploader\n *\n * @param {HTMLElement} element The current HTML element\n * @param {string} selector The CSS selector to match\n * @returns\n */\nconst getNextMatchingSibling = (element, selector) => {\n let sibling = element.nextElementSibling;\n\n while (sibling) {\n if (sibling.matches(selector)) return sibling;\n sibling = sibling.nextElementSibling;\n }\n};\n\n/**\n * Returns the previous sibling in the DOM which matches the given CSS selector.\n * This makes sure that only toolbar buttons are cycled through on Arrow key press,\n * and not e.g. the hidden file input from ImageUploader\n *\n * @param {HTMLElement} element The current HTML element\n * @param {string} selector The CSS selector to match\n * @returns\n */\nconst getPreviousMatchingSibling = (element, selector) => {\n let sibling = element.previousElementSibling;\n\n while (sibling) {\n if (sibling.matches(selector)) return sibling;\n sibling = sibling.previousElementSibling;\n }\n};\n\n/**\n * UI component providing markdown shortcuts, to be inserted into the textarea with the given ID\n *\n * @param {object} props\n * @param {string} props.textAreaId The ID of the textarea the markdown formatting should be added to\n */\nexport const MarkdownToolbar = ({\n textAreaId,\n additionalSecondaryToolbarElements = [],\n}) => {\n const textAreaRef = useRef(null);\n\n const [overflowMenuOpen, setOverflowMenuOpen] = useState(false);\n const [storedCursorPosition, setStoredCursorPosition] = useState({});\n const smallScreen = useMediaQuery(`(max-width: ${BREAKPOINTS.Medium - 1}px)`);\n const largeScreen = useMediaQuery(\n `(min-width: ${BREAKPOINTS.Large}px) and (max-width: ${\n BREAKPOINTS.ExtraLarge - 1\n }px)`,\n );\n\n const overflowMenuRows = smallScreen ? 2 : 1;\n\n // Enhance any additional toolbar elements with the appropriate roles & listeners\n const additionalSecondaryItems = additionalSecondaryToolbarElements.map(\n (SecondaryItem) =>\n cloneElement(SecondaryItem, {\n role: 'menuitem',\n className: 'overflow-menu-btn',\n tabindex: '-1',\n onKeyUp: (e) => handleToolbarButtonKeyPress(e, 'overflow-menu-btn'),\n }),\n );\n\n const keyboardShortcuts = Object.fromEntries(\n Object.keys(markdownSyntaxFormatters)\n .filter(\n (syntaxName) =>\n !!markdownSyntaxFormatters[syntaxName].getKeyboardShortcut,\n )\n .map((syntaxName) => {\n const { command } =\n markdownSyntaxFormatters[syntaxName].getKeyboardShortcut();\n return [\n command,\n (e) => {\n e.preventDefault();\n insertSyntax(syntaxName);\n },\n ];\n }),\n );\n\n useKeyboardShortcuts(keyboardShortcuts, textAreaRef.current);\n\n useLayoutEffect(() => {\n textAreaRef.current = document.getElementById(textAreaId);\n }, [textAreaId]);\n\n useLayoutEffect(() => {\n // If a user resizes their screen, make sure roving tabindex continues to operate\n const focusableToolbarButton = document.querySelector(\n '.toolbar-btn[tabindex=\"0\"]',\n );\n if (!focusableToolbarButton) {\n document.querySelector('.toolbar-btn').setAttribute('tabindex', '0');\n }\n }, [smallScreen, largeScreen]);\n\n useLayoutEffect(() => {\n const clickOutsideHandler = ({ target }) => {\n if (target.id !== 'overflow-menu-button') {\n setOverflowMenuOpen(false);\n }\n };\n\n const escapePressHandler = ({ key }) => {\n if (key === 'Escape') {\n setOverflowMenuOpen(false);\n document.getElementById('overflow-menu-button').focus();\n }\n if (key === 'Tab') {\n setOverflowMenuOpen(false);\n }\n };\n\n if (overflowMenuOpen) {\n document\n .getElementById('overflow-menu')\n .getElementsByClassName('overflow-menu-btn')[0]\n .focus();\n\n document.addEventListener('keyup', escapePressHandler);\n document.addEventListener('click', clickOutsideHandler);\n } else {\n document.removeEventListener('keyup', escapePressHandler);\n document.removeEventListener('click', clickOutsideHandler);\n }\n\n return () => {\n document.removeEventListener('keyup', escapePressHandler);\n document.removeEventListener('click', clickOutsideHandler);\n };\n }, [overflowMenuOpen]);\n\n // Handles keyboard 'roving tabindex' pattern for toolbar\n const handleToolbarButtonKeyPress = (event, className) => {\n const { key, target } = event;\n\n const nextButton = getNextMatchingSibling(target, `.${className}`);\n const previousButton = getPreviousMatchingSibling(target, `.${className}`);\n\n switch (key) {\n case 'ArrowRight':\n event.preventDefault();\n target.setAttribute('tabindex', '-1');\n if (nextButton) {\n nextButton.setAttribute('tabindex', 0);\n nextButton.focus();\n } else {\n const firstButton = document.querySelector(`.${className}`);\n firstButton.setAttribute('tabindex', '0');\n firstButton.focus();\n }\n break;\n case 'ArrowLeft':\n event.preventDefault();\n target.setAttribute('tabindex', '-1');\n if (previousButton) {\n previousButton.setAttribute('tabindex', 0);\n previousButton.focus();\n } else {\n const allButtons = document.getElementsByClassName(className);\n const lastButton = allButtons[allButtons.length - 1];\n lastButton.setAttribute('tabindex', '0');\n lastButton.focus();\n }\n break;\n case 'ArrowDown':\n if (target.id === 'overflow-menu-button') {\n event.preventDefault();\n setOverflowMenuOpen(true);\n }\n break;\n }\n };\n\n const insertSyntax = (syntaxName) => {\n setOverflowMenuOpen(false);\n\n const { current: textArea } = textAreaRef;\n const {\n newCursorStart,\n newCursorEnd,\n editSelectionStart,\n editSelectionEnd,\n replaceSelectionWith,\n } = markdownSyntaxFormatters[syntaxName].getFormatting(textArea);\n\n // We try to update the textArea with document.execCommand, which requires the contentEditable attribute to be true.\n // The value is later toggled back to 'false'\n textArea.contentEditable = 'true';\n textArea.focus({ preventScroll: true });\n textArea.setSelectionRange(editSelectionStart, editSelectionEnd);\n\n try {\n // We first try to use execCommand which allows the change to be correctly added to the undo queue.\n // document.execCommand is deprecated, but the API which will eventually replace it is still incoming (https://w3c.github.io/input-events/)\n if (replaceSelectionWith === '') {\n document.execCommand('delete', false);\n } else {\n document.execCommand('insertText', false, replaceSelectionWith);\n }\n } catch {\n // In the event of any error using execCommand, we make sure the text area updates (but undo queue will not)\n textArea.value = getNewTextAreaValueWithEdits({\n textAreaValue: textArea.value,\n editSelectionStart,\n editSelectionEnd,\n replaceSelectionWith,\n });\n }\n\n textArea.contentEditable = 'false';\n textArea.dispatchEvent(new Event('input'));\n textArea.setSelectionRange(newCursorStart, newCursorEnd);\n };\n\n const handleImageUploadStarted = () => {\n const { current: textArea } = textAreaRef;\n const { textBeforeSelection, textAfterSelection } =\n getSelectionData(textArea);\n\n const { selectionEnd } = storedCursorPosition;\n\n const textWithPlaceholder = `${textBeforeSelection}\\n${UPLOADING_IMAGE_PLACEHOLDER}${textAfterSelection}`;\n textArea.value = textWithPlaceholder;\n // Make sure Editor text area updates via linkstate\n textArea.dispatchEvent(new Event('input'));\n\n textArea.focus({ preventScroll: true });\n\n // Set cursor to the end of the placeholder\n const newCursorPosition =\n selectionEnd + UPLOADING_IMAGE_PLACEHOLDER.length + 1;\n\n textArea.setSelectionRange(newCursorPosition, newCursorPosition);\n };\n\n const handleImageUploadEnd = (imageMarkdown = '') => {\n const { current: textArea } = textAreaRef;\n\n const {\n selectionStart,\n selectionEnd,\n value: currentTextAreaValue,\n } = textArea;\n\n const indexOfPlaceholder = currentTextAreaValue.indexOf(\n UPLOADING_IMAGE_PLACEHOLDER,\n );\n\n // User has deleted placeholder, nothing to do\n if (indexOfPlaceholder === -1) return;\n\n const newTextValue = textArea.value.replace(\n UPLOADING_IMAGE_PLACEHOLDER,\n imageMarkdown,\n );\n\n textArea.value = newTextValue;\n // Make sure Editor text area updates via linkstate\n textArea.dispatchEvent(new Event('input'));\n\n // The change to image markdown length does not affect cursor position\n if (indexOfPlaceholder > selectionStart) {\n textArea.setSelectionRange(selectionStart, selectionEnd);\n return;\n }\n\n const differenceInLength =\n imageMarkdown.length - UPLOADING_IMAGE_PLACEHOLDER.length;\n\n textArea.setSelectionRange(\n selectionStart + differenceInLength,\n selectionEnd + differenceInLength,\n );\n };\n\n const numberOfCoreFormatters = getNumberOfIconsToDisplayInToolbar({\n isSmallScreen: smallScreen,\n isLargeScreen: largeScreen,\n });\n\n const coreSyntaxFormatters = Object.fromEntries(\n Object.entries(markdownSyntaxFormatters).slice(0, numberOfCoreFormatters),\n );\n const secondarySyntaxFormatters = Object.fromEntries(\n Object.entries(markdownSyntaxFormatters).slice(numberOfCoreFormatters),\n );\n\n const secondaryFormatterButtons = Object.keys(secondarySyntaxFormatters).map(\n (controlName, index) => {\n const { icon, label, getKeyboardShortcut } =\n secondarySyntaxFormatters[controlName];\n\n return (\n insertSyntax(controlName)}\n onKeyUp={(e) => handleToolbarButtonKeyPress(e, 'overflow-menu-btn')}\n aria-label={label}\n tooltip={\n smallScreen ? null : (\n \n {label}\n {getKeyboardShortcut ? (\n \n {` ${getKeyboardShortcut().tooltipHint}`}\n \n ) : null}\n \n )\n }\n />\n );\n },\n );\n\n return (\n \n {Object.keys(coreSyntaxFormatters).map((controlName, index) => {\n const { icon, label, getKeyboardShortcut } =\n coreSyntaxFormatters[controlName];\n return (\n insertSyntax(controlName)}\n onKeyUp={(e) => handleToolbarButtonKeyPress(e, 'toolbar-btn')}\n aria-label={label}\n tooltip={\n smallScreen ? null : (\n \n {label}\n {getKeyboardShortcut ? (\n \n {` ${getKeyboardShortcut().tooltipHint}`}\n \n ) : null}\n \n )\n }\n />\n );\n })}\n\n handleToolbarButtonKeyPress(e, 'toolbar-btn'),\n onClick: () => {\n const {\n current: { selectionStart, selectionEnd },\n } = textAreaRef;\n setStoredCursorPosition({ selectionStart, selectionEnd });\n },\n tooltip: smallScreen ? null : (\n Upload image\n ),\n key: 'image-btn',\n className: 'toolbar-btn formatter-btn mr-1',\n tabindex: '-1',\n }}\n />\n\n setOverflowMenuOpen(!overflowMenuOpen)}\n onKeyUp={(e) => handleToolbarButtonKeyPress(e, 'toolbar-btn')}\n aria-expanded={overflowMenuOpen ? 'true' : 'false'}\n aria-haspopup=\"true\"\n icon={OverflowIcon}\n className=\"toolbar-btn ml-auto\"\n tabindex=\"-1\"\n aria-label=\"More options\"\n />\n\n {overflowMenuOpen && (\n \n {secondaryFormatterButtons}\n {additionalSecondaryItems}\n \n )}\n \n );\n};\n","import { h } from 'preact';\nimport PropTypes from 'prop-types';\nimport { Icon, ButtonNew as Button } from '@crayons';\nimport { Close } from '@images/x.svg';\n\n/**\n * Responsible for the layout of a selected item in the crayons autocomplete and multi input components\n *\n * @param {string} name The selected item name\n * @param {string} buttonVariant Optional button variant\n * @param {string} className Optional classname for selected item\n * @param {Function} onEdit Callback for edit click on the name of the selected item\n * @param {Function} onDeselect Callback for deselect click on the close icon\n */\nexport const DefaultSelectionTemplate = ({\n name,\n enableValidation = false,\n valid = true,\n buttonVariant = 'default',\n className = 'c-autocomplete--multi__selected',\n onEdit,\n onDeselect,\n}) => {\n const conditionalAttributes = () => {\n if (enableValidation) {\n return { 'aria-describedby': `invalid-item-${name}` };\n }\n return {};\n };\n\n return (\n <>\n {enableValidation && (\n \n {!valid ? 'Invalid entry' : ''}\n \n )}\n
\n \n {name}\n \n \n \n \n
\n \n );\n};\n\nDefaultSelectionTemplate.propTypes = {\n name: PropTypes.string.isRequired,\n buttonVariant: PropTypes.string,\n className: PropTypes.string,\n onEdit: PropTypes.func.isRequired,\n onDeselect: PropTypes.func.isRequired,\n};\n","/* eslint-disable jsx-a11y/interactive-supports-focus, jsx-a11y/role-has-required-aria-props */\n// Disabled due to the linter being out of date for combobox role: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/789\nimport { h, Fragment } from 'preact';\nimport PropTypes from 'prop-types';\nimport { useEffect, useRef, useReducer } from 'preact/hooks';\nimport { DefaultSelectionTemplate } from '../../shared/components/defaultSelectionTemplate';\n\nconst KEYS = {\n UP: 'ArrowUp',\n DOWN: 'ArrowDown',\n ENTER: 'Enter',\n ESCAPE: 'Escape',\n DELETE: 'Backspace',\n COMMA: ',',\n SPACE: ' ',\n};\n\nconst ALLOWED_CHARS_REGEX = /([a-zA-Z0-9])/;\nconst PLACEHOLDER_SELECTIONS_MADE = 'Add another...';\n\nconst reducer = (state, action) => {\n switch (action.type) {\n case 'setSelectedItems':\n return {\n ...state,\n selectedItems: action.payload.selectedItems,\n suggestions: action.payload.suggestions ?? state.suggestions,\n activeDescendentIndex: null,\n };\n case 'setSuggestions':\n return {\n ...state,\n suggestions: action.payload,\n activeDescendentIndex: null,\n };\n case 'updateEditState':\n return {\n ...state,\n editValue: action.payload.editValue,\n inputPosition: action.payload.inputPosition,\n };\n case 'setActiveDescendentIndex':\n return { ...state, activeDescendentIndex: action.payload };\n case 'setIgnoreBlur':\n return { ...state, ignoreBlur: action.payload };\n case 'setShowMaxSelectionsReached':\n return { ...state, showMaxSelectionsReached: action.payload };\n default:\n return state;\n }\n};\n\n/**\n * Component allowing users to search and select multiple values\n *\n * @param {Object} props\n * @param {string} props.labelText The text for the input's label\n * @param {boolean} props.showLabel Whether the label text should be visible or hidden (for assistive tech users only)\n * @param {Function} props.fetchSuggestions Callback function which accepts the search term string and returns an array of suggestions\n * @param {Array} props.defaultValue Array of items which should be selected by default\n * @param {Array} props.staticSuggestions Array of items which should be suggested if no search term has been entered yet\n * @param {string} props.staticSuggestionsHeading Optional heading to display when static suggestions are rendered\n * @param {boolean} props.border Whether to show a bordered input\n * @param {string} props.placeholder Input placeholder text\n * @param {string} props.inputId ID to be applied to the input element\n * @param {number} props.maxSelections Optional maximum number of allowed selections\n * @param {Function} props.onSelectionsChanged Callback for when selections are added or removed\n * @param {Function} props.onFocus Callback for when the component receives focus\n * @param {boolean} props.allowUserDefinedSelections Whether a user can create new selections other than the defined suggestions\n * @param {Function} props.SuggestionTemplate Optional Preact component to render suggestion items\n * @param {Function} props.SelectionTemplate Optional Preact component to render selected items\n */\nexport const MultiSelectAutocomplete = ({\n labelText,\n showLabel = true,\n fetchSuggestions,\n defaultValue = [],\n staticSuggestions = [],\n staticSuggestionsHeading,\n border = true,\n placeholder = 'Add...',\n inputId,\n maxSelections,\n onSelectionsChanged,\n onFocus,\n allowUserDefinedSelections = false,\n SuggestionTemplate,\n SelectionTemplate = DefaultSelectionTemplate,\n}) => {\n const [state, dispatch] = useReducer(reducer, {\n suggestions: [],\n selectedItems: defaultValue,\n inputPosition: null,\n editValue: null,\n activeDescendentIndex: null,\n ignoreBlur: false,\n showMaxSelectionsReached: false,\n });\n\n const {\n selectedItems,\n suggestions,\n inputPosition,\n editValue,\n activeDescendentIndex,\n ignoreBlur,\n showMaxSelectionsReached,\n } = state;\n\n const inputRef = useRef(null);\n const inputSizerRef = useRef(null);\n const selectedItemsRef = useRef(null);\n const popoverRef = useRef(null);\n\n const allowSelections =\n !maxSelections || selectedItems.length < maxSelections;\n\n useEffect(() => {\n if (defaultValue.length > 0) {\n dispatch({\n type: 'setSelectedItems',\n payload: {\n selectedItems: defaultValue,\n },\n });\n }\n }, [defaultValue]);\n\n const handleInputBlur = () => {\n dispatch({ type: 'setShowMaxSelectionsReached', payload: false });\n\n const {\n current: { value: currentValue },\n } = inputRef;\n\n // The input will blur when user selects an option from the dropdown via mouse click. The ignoreBlur boolean lets us know we can ignore this event.\n if (!ignoreBlur && allowSelections && currentValue !== '') {\n selectByText({ textValue: currentValue, keepSelecting: false });\n return;\n }\n if (!ignoreBlur) {\n // Clear the suggestions if a genuine blur event\n dispatch({ type: 'setSuggestions', payload: [] });\n }\n exitEditState({ keepSelecting: false });\n dispatch({ type: 'setIgnoreBlur', payload: false });\n };\n\n useEffect(() => {\n // editValue defaults to null when component is first rendered.\n // This ensures we do not autofocus the input before the user has started interacting with the component.\n if (editValue === null) {\n return;\n }\n\n const { current: input } = inputRef;\n if (input && inputPosition !== null) {\n // Entering 'edit' mode\n resizeInputToContentSize();\n\n input.value = editValue;\n const { length: cursorPosition } = editValue;\n\n input.focus();\n input.setSelectionRange(cursorPosition, cursorPosition);\n\n // Trigger the input event to make sure suggestion UI updates correctly\n const changeEvent = new Event('input');\n input.dispatchEvent(changeEvent);\n }\n }, [inputPosition, editValue]);\n\n useEffect(() => {\n if (activeDescendentIndex !== null) {\n const { current: popover } = popoverRef;\n const activeItem = popover?.querySelector('[aria-selected=\"true\"]');\n if (!popover || !activeItem) {\n return;\n }\n\n // Make sure that the active item is scrolled into view, if need be\n const { offsetHeight, offsetTop } = activeItem;\n const { offsetHeight: popoverOffsetHeight, scrollTop } = popover;\n\n const isAbove = offsetTop < scrollTop;\n const isBelow =\n offsetTop + offsetHeight > scrollTop + popoverOffsetHeight;\n\n if (isAbove) {\n popover.scrollTo(0, offsetTop);\n } else if (isBelow) {\n popover.scrollTo(0, offsetTop - popoverOffsetHeight + offsetHeight);\n }\n }\n }, [activeDescendentIndex]);\n\n const selectByText = ({\n textValue,\n nextInputValue = '',\n keepSelecting = true,\n }) => {\n const matchingSuggestion = suggestions.find(\n (suggestion) => suggestion.name === textValue,\n );\n\n if (matchingSuggestion) {\n selectItem({\n selectedItem: matchingSuggestion,\n nextInputValue,\n keepSelecting,\n });\n return;\n }\n\n // If we allow user's own input as a selection, fallback to that\n if (allowUserDefinedSelections) {\n selectItem({\n selectedItem: { name: textValue },\n nextInputValue,\n keepSelecting,\n });\n return;\n }\n\n // If we couldn't select any valid input, and search is terminated, clear the input\n if (!keepSelecting) {\n inputRef.current.value = '';\n dispatch('setSuggestions', { payload: [] });\n }\n };\n\n const enterEditState = (editItem, editItemIndex) => {\n inputSizerRef.current.innerText = editItem.name;\n deselectItem(editItem);\n\n dispatch({\n type: 'updateEditState',\n payload: {\n editValue: editItem.name,\n inputPosition: editItemIndex,\n },\n });\n };\n\n const exitEditState = ({ nextInputValue = '', keepSelecting = true }) => {\n // Reset 'edit mode' input resizing\n inputRef.current?.style?.removeProperty('width');\n inputSizerRef.current.innerText = nextInputValue;\n\n dispatch({\n type: 'updateEditState',\n payload: {\n editValue: nextInputValue,\n inputPosition: nextInputValue === '' ? null : inputPosition + 1,\n },\n });\n\n // Blurring away while clearing the input\n if (!keepSelecting && nextInputValue === '') {\n inputRef.current.value = '';\n }\n };\n\n const resizeInputToContentSize = () => {\n const { current: input } = inputRef;\n\n if (input) {\n input.style.width = `${inputSizerRef.current.clientWidth}px`;\n }\n };\n\n const handleAutocompleteStart = () => {\n // Only show static suggestions when not in edit mode\n if (inputPosition !== null) {\n return;\n }\n\n // If we've already reached max selections, show the message rather than static suggestions\n if (!allowSelections) {\n dispatch({ type: 'setShowMaxSelectionsReached', payload: true });\n return;\n }\n\n // If we have static suggestions, and no search term, show the static suggestions\n if (staticSuggestions.length > 0 && inputRef.current?.value === '') {\n dispatch({\n type: 'setSuggestions',\n payload: staticSuggestions.filter(\n (item) =>\n !selectedItems.some(\n (selectedItem) => selectedItem.name === item.name,\n ),\n ),\n });\n }\n };\n\n const handleInputChange = async ({ target: { value } }) => {\n // When the input appears inline in \"edit\" mode, we need to dynamically calculate the width to ensure it occupies the right space\n // (an input cannot resize based on its text content). We use a hidden to track the size.\n inputSizerRef.current.innerText = value;\n\n if (inputPosition !== null) {\n resizeInputToContentSize();\n }\n\n // If max selections have already been reached, no need to fetch further suggestions\n if (!allowSelections) {\n return;\n }\n\n if (value === '') {\n dispatch({\n type: 'setSuggestions',\n payload: staticSuggestions.filter(\n (item) =>\n !selectedItems.some(\n (selectedItem) => selectedItem.name === item.name,\n ),\n ),\n });\n return;\n }\n\n const results = await fetchSuggestions(value);\n\n // It could be that while waiting on the network fetch, the user has already made a selection or otherwise cleared the input\n if (inputRef.current.value === '') {\n return;\n }\n\n // If no results, and user-generated selections are allowed, display current search term as an option\n if (allowUserDefinedSelections && results.length === 0 && value !== '') {\n results.push({ name: value });\n }\n\n dispatch({\n type: 'setSuggestions',\n payload: results.filter(\n (item) =>\n !selectedItems.some(\n (selectedItem) => selectedItem.name === item.name,\n ),\n ),\n });\n };\n\n const clearInput = () => {\n inputRef.current.value = '';\n dispatch({ type: 'setSuggestions', payload: [] });\n };\n\n const handleKeyDown = (e) => {\n const { selectionStart, value: currentValue } = inputRef.current;\n\n switch (e.key) {\n case KEYS.DOWN:\n e.preventDefault();\n\n if (\n activeDescendentIndex !== null &&\n activeDescendentIndex < suggestions.length - 1\n ) {\n dispatch({\n type: 'setActiveDescendentIndex',\n payload: activeDescendentIndex + 1,\n });\n } else {\n dispatch({ type: 'setActiveDescendentIndex', payload: 0 });\n }\n break;\n case KEYS.UP:\n e.preventDefault();\n\n dispatch({\n type: 'setActiveDescendentIndex',\n payload:\n activeDescendentIndex >= 1\n ? activeDescendentIndex - 1\n : suggestions.length - 1,\n });\n\n break;\n case KEYS.ENTER:\n e.preventDefault();\n if (activeDescendentIndex !== null) {\n selectItem({ selectedItem: suggestions[activeDescendentIndex] });\n }\n break;\n case KEYS.ESCAPE:\n e.preventDefault();\n // Clear the input and suggestions\n clearInput();\n break;\n case KEYS.COMMA:\n case KEYS.SPACE:\n e.preventDefault();\n // Accept whatever is in the input before the comma or space.\n // If any text remains after the comma or space, the edit will continue separately\n if (currentValue !== '' && allowSelections) {\n selectByText({\n textValue: currentValue.slice(0, selectionStart),\n nextInputValue: currentValue.slice(selectionStart),\n });\n }\n break;\n case KEYS.DELETE:\n if (currentValue === '') {\n e.preventDefault();\n editPreviousSelectionIfExists();\n }\n break;\n default:\n if (!ALLOWED_CHARS_REGEX.test(e.key)) {\n e.preventDefault();\n }\n }\n };\n\n // If there is a previous selection, then pop it into edit mode\n const editPreviousSelectionIfExists = () => {\n if (selectedItems.length > 0 && inputPosition !== 0) {\n const nextEditIndex =\n inputPosition !== null ? inputPosition - 1 : selectedItems.length - 1;\n\n const item = selectedItems[nextEditIndex];\n deselectItem(item);\n enterEditState(item, nextEditIndex);\n }\n };\n\n const getEmptyInputSuggestions = ({ currentSelections = selectedItems }) => {\n if (staticSuggestions.length > 0) {\n return staticSuggestions.filter(\n (suggestion) =>\n !currentSelections.some(\n (selection) => selection.name === suggestion.name,\n ),\n );\n }\n\n return [];\n };\n\n const selectItem = ({\n selectedItem,\n nextInputValue = '',\n keepSelecting = true,\n }) => {\n // If a user has manually typed an item already selected, reset\n if (selectedItems.some((item) => item.name === selectedItem.name)) {\n clearInput();\n return;\n }\n\n // If an item was edited, we want to keep it in the same position in the list\n const insertIndex =\n inputPosition !== null ? inputPosition : selectedItems.length;\n const newSelections = [\n ...selectedItems.slice(0, insertIndex),\n selectedItem,\n ...selectedItems.slice(insertIndex),\n ];\n\n // We update the hidden selected items list, so additions are announced to screen reader users\n const listItem = document.createElement('li');\n listItem.innerText = selectedItem.name;\n selectedItemsRef.current.appendChild(listItem);\n\n exitEditState({ nextInputValue, keepSelecting });\n\n dispatch({\n type: 'setSelectedItems',\n payload: {\n selectedItems: newSelections,\n suggestions: keepSelecting\n ? getEmptyInputSuggestions({\n currentSelections: newSelections,\n })\n : [],\n },\n });\n\n onSelectionsChanged?.(newSelections);\n\n // Clear the text input\n const { current: input } = inputRef;\n input.value = nextInputValue;\n\n if (keepSelecting) {\n dispatch({\n type: 'setShowMaxSelectionsReached',\n payload: maxSelections && newSelections.length >= maxSelections,\n });\n\n // setTimeout is used with no delay here to make sure this focus event is executed in the next event cycle.\n // selectItem() happens on mousedown rather than click, because mousedown is handled before the blur event, and we\n // want to ignore some blur events (i.e. when input blurs because user has clicked a dropdown option).\n // By using setTimeout, we make sure that the normal blur event is handled before we try to refocus the input.\n setTimeout(() => {\n input.focus();\n });\n }\n };\n\n const deselectItem = (deselectedItem) => {\n const newSelections = selectedItems.filter(\n (item) => item.name !== deselectedItem.name,\n );\n dispatch({\n type: 'setSelectedItems',\n payload: {\n selectedItems: newSelections,\n suggestions,\n },\n });\n\n dispatch({\n type: 'setShowMaxSelectionsReached',\n payload: maxSelections && newSelections.length >= maxSelections,\n });\n\n onSelectionsChanged?.(newSelections);\n\n // We also update the hidden selected items list, so removals are announced to screen reader users\n selectedItemsRef.current.querySelectorAll('li').forEach((selectionNode) => {\n if (selectionNode.innerText === deselectedItem.name) {\n selectionNode.remove();\n }\n });\n };\n\n const allSelectedItemElements = selectedItems.map((item, index) => {\n // When we are in \"edit mode\" we visually display the input between the other selections\n const defaultPosition = index + 1;\n const appearsBeforeInput = inputPosition === null || index < inputPosition;\n const position = appearsBeforeInput ? defaultPosition : defaultPosition + 1;\n\n const { name: displayName } = item;\n return (\n \n enterEditState(item, index)}\n onDeselect={() => deselectItem(item)}\n />\n \n );\n });\n\n const selectionsPlaceholder =\n selectedItems.length > 0 ? PLACEHOLDER_SELECTIONS_MADE : placeholder;\n\n const inputPlaceholder = allowSelections ? selectionsPlaceholder : null;\n\n return (\n \n \n \n {labelText}\n \n \n {maxSelections ? `Maximum ${maxSelections} selections` : ''}\n \n\n {/* A visually hidden list provides confirmation messages to screen reader users as an item is selected or removed */}\n
\n

Selected items:

\n \n
\n\n
\n {/* disabled as the inner input forms the tab stop (this click handler ensures _any_ click on the wrapper focuses the input which may be less wide) */}\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}\n 0}\n aria-owns=\"listbox1\"\n className={`c-autocomplete--multi__wrapper${\n border ? '-border crayons-textfield' : ' border-none p-0'\n } flex items-center cursor-text`}\n onClick={() => inputRef.current?.focus()}\n >\n
    \n {allSelectedItemElements}\n\n \n {\n onFocus?.(e);\n handleAutocompleteStart();\n }}\n placeholder={inputPosition === null ? inputPlaceholder : null}\n />\n \n
\n
\n {showMaxSelectionsReached ? (\n
\n Only {maxSelections} selections allowed\n
\n ) : null}\n {suggestions.length > 0 && allowSelections ? (\n
\n {inputRef.current?.value === '' ? staticSuggestionsHeading : null}\n \n {suggestions.map((suggestion, index) => {\n const { name: suggestionDisplayName } = suggestion;\n return (\n {\n selectItem({ selectedItem: suggestion });\n dispatch({ type: 'setIgnoreBlur', payload: true });\n }}\n >\n {SuggestionTemplate ? (\n \n ) : (\n suggestionDisplayName\n )}\n \n );\n })}\n \n
\n ) : null}\n \n
\n );\n};\n\nconst optionPropType = PropTypes.shape({ name: PropTypes.string });\n\nMultiSelectAutocomplete.propTypes = {\n labelText: PropTypes.string.isRequired,\n showLabel: PropTypes.bool,\n fetchSuggestions: PropTypes.func.isRequired,\n defaultValue: PropTypes.arrayOf(optionPropType),\n staticSuggestions: PropTypes.arrayOf(optionPropType),\n staticSuggestionsHeading: PropTypes.oneOfType([\n PropTypes.element,\n PropTypes.string,\n ]),\n border: PropTypes.bool,\n placeholder: PropTypes.string,\n inputId: PropTypes.string,\n maxSelections: PropTypes.number,\n onSelectionsChanged: PropTypes.func,\n onFocus: PropTypes.func,\n SuggestionTemplate: PropTypes.func,\n SelectionTemplate: PropTypes.func,\n};\n","let isFullScreenModeCodeOn = false;\nlet screenScroll = 0;\nconst fullScreenWindow =\n document.getElementsByClassName('js-fullscreen-code')[0];\nconst { body } = document;\n\nfunction setAfterFullScreenScrollPosition() {\n window.scrollTo(0, screenScroll);\n}\n\nfunction getBeforeFullScreenScrollPosition() {\n screenScroll = window.scrollY;\n}\n\nfunction onPressEscape(event) {\n if (event.key == 'Escape') {\n fullScreenModeControl(event);\n }\n}\n\nfunction listenToKeyboardForEscape(listen) {\n if (listen) {\n document.body.addEventListener('keyup', onPressEscape);\n } else {\n document.body.removeEventListener('keyup', onPressEscape);\n }\n}\n\nfunction toggleOverflowForDocument(overflow) {\n if (overflow) {\n body.style.overflow = 'hidden';\n } else {\n body.style.overflow = '';\n }\n}\n\nexport function addFullScreenModeControl(elements) {\n if (elements) {\n for (const element of elements) {\n element.addEventListener('click', fullScreenModeControl);\n }\n }\n}\n\nfunction removeFullScreenModeControl(elements) {\n if (elements) {\n for (const element of elements) {\n element.removeEventListener('click', fullScreenModeControl);\n }\n }\n}\n\nfunction fullScreenModeControl(event) {\n const codeBlock = event.currentTarget.closest('.js-code-highlight')\n ? event.currentTarget.closest('.js-code-highlight').cloneNode(true)\n : null;\n const codeBlockControls = codeBlock\n ? codeBlock.getElementsByClassName('js-fullscreen-code-action')\n : null;\n\n if (isFullScreenModeCodeOn) {\n toggleOverflowForDocument(false);\n setAfterFullScreenScrollPosition();\n listenToKeyboardForEscape(false);\n removeFullScreenModeControl(codeBlockControls);\n\n fullScreenWindow.classList.remove('is-open');\n fullScreenWindow.removeChild(fullScreenWindow.childNodes[0]);\n\n isFullScreenModeCodeOn = false;\n } else {\n toggleOverflowForDocument(true);\n getBeforeFullScreenScrollPosition();\n listenToKeyboardForEscape(true);\n codeBlock.classList.add('is-fullscreen');\n fullScreenWindow.appendChild(codeBlock);\n fullScreenWindow.classList.add('is-open');\n\n addFullScreenModeControl(codeBlockControls);\n\n isFullScreenModeCodeOn = true;\n }\n}\n","import PropTypes from 'prop-types';\n\nexport const userPropTypes = PropTypes.shape({\n id: PropTypes.string.isRequired,\n name: PropTypes.string.isRequired,\n profile_image_url: PropTypes.string.isRequired,\n summary: PropTypes.string.isRequired,\n});\n","import PropTypes from 'prop-types';\n\nexport const selectedTagsPropTypes = PropTypes.shape({\n tags: PropTypes.arrayOf(PropTypes.string).isRequired,\n onClick: PropTypes.func.isRequired,\n onKeyPress: PropTypes.func.isRequired,\n});\n","import { getUserDataAndCsrfToken } from '@utilities/getUserDataAndCsrfToken';\nimport {\n closeWindowModal,\n showWindowModal,\n WINDOW_MODAL_ID,\n} from '@utilities/showModal';\n/* global userData */\n\nfunction toggleSubscribeActionUI({\n tagContainer,\n showSubscribeAction = false,\n appleAuth = false,\n}) {\n const signedInUI = tagContainer.getElementsByClassName(\n 'ltag__user-subscription-tag__signed-in',\n )[0];\n\n const appleAuthUI = tagContainer.getElementsByClassName(\n 'ltag__user-subscription-tag__apple-auth',\n )[0];\n\n if (!showSubscribeAction) {\n appleAuthUI.classList.add('hidden');\n signedInUI.classList.add('hidden');\n return;\n }\n\n // In this case we don't have an email we can use, and need the user to update their settings first\n if (appleAuth) {\n signedInUI.classList.add('hidden');\n appleAuthUI.classList.remove('hidden');\n return;\n }\n\n signedInUI.classList.remove('hidden');\n}\n\nfunction toggleSignedOutUI(tagContainer, showSignedOutUI = false) {\n const signedOutUI = tagContainer.getElementsByClassName(\n 'ltag__user-subscription-tag__signed-out',\n )[0];\n if (showSignedOutUI) {\n signedOutUI.classList.remove('hidden');\n } else {\n signedOutUI.classList.add('hidden');\n }\n}\n\nfunction updateProfileImagesUI(tagContainer, signedIn = false) {\n const profileImagesContainer = tagContainer.getElementsByClassName(\n 'ltag__user-subscription-tag__profile-images',\n )[0];\n\n if (signedIn) {\n profileImagesContainer.classList.add('signed-in');\n profileImagesContainer.classList.remove('signed-out');\n\n tagContainer\n .getElementsByClassName(\n 'ltag__user-subscription-tag__subscriber-profile-image',\n )[0]\n .classList.remove('hidden');\n } else {\n profileImagesContainer.classList.remove('signed-in');\n profileImagesContainer.classList.add('signed-out');\n\n tagContainer\n .getElementsByClassName(\n 'ltag__user-subscription-tag__subscriber-profile-image',\n )[0]\n .classList.add('hidden');\n }\n}\n\nfunction initSignedOutState(tagContainer) {\n toggleSubscribeActionUI({ tagContainer, showSubscribeAction: false });\n toggleSignedOutUI(tagContainer, true);\n updateProfileImagesUI(tagContainer, false);\n}\n\nfunction initSignedInState(tagContainer, appleAuth = false) {\n toggleSubscribeActionUI({\n tagContainer,\n showSubscribeAction: true,\n appleAuth,\n });\n toggleSignedOutUI(tagContainer, false);\n updateProfileImagesUI(tagContainer, true);\n\n tagContainer\n .querySelector('.ltag__user-subscription-tag__signed-in .crayons-btn')\n .addEventListener('click', () => {\n showConfirmSubscribeModal();\n });\n}\n\nfunction showConfirmSubscribeModal() {\n showWindowModal({\n title: 'Confirm subscribe',\n size: 'small',\n modalContent: document.querySelector(\n '.user-subscription-confirmation-modal .crayons-modal__box__body',\n ).innerHTML,\n onOpen: () => {\n // Attach listeners for cancel button and subscribe button\n document\n .querySelector(\n `#${WINDOW_MODAL_ID} .ltag__user-subscription-tag____cancel-btn`,\n )\n .addEventListener('click', () => {\n closeWindowModal();\n });\n\n document\n .querySelector(\n `#${WINDOW_MODAL_ID} .ltag__user-subscription-tag__confirmation-btn`,\n )\n .addEventListener('click', confirmSubscribe);\n },\n });\n}\n\nfunction confirmSubscribe() {\n closeWindowModal();\n clearNotices();\n\n submitSubscription().then((response) => {\n if (response.success) {\n const allSubscriptionLiquidTags = document.getElementsByClassName(\n 'ltag__user-subscription-tag',\n );\n\n showSubscribedNotices();\n\n for (const tagContainer of allSubscriptionLiquidTags) {\n // We no longer want to show the submit button since user is now subscribed\n toggleSubscribeActionUI({ tagContainer, showSubscribeAction: false });\n }\n } else {\n updateNotices({ variant: 'danger', content: response.error });\n // Allow user to retry\n toggleSubmitButtonsState({ disabled: false, textContent: 'Subscribe' });\n }\n });\n}\n\nfunction toggleSubmitButtonsState({ disabled, textContent }) {\n // Since all user sub tags on the same article page perform the same action, all submit buttons are kept in sync\n const allUserSubLiquidTagSubmits = document.querySelectorAll(\n '.ltag__user-subscription-tag__signed-in .crayons-btn',\n );\n\n for (const submit of allUserSubLiquidTagSubmits) {\n submit.disabled = disabled;\n submit.textContent = textContent;\n }\n}\n\nfunction updateNotices({ variant, content }) {\n const allNotices = document.getElementsByClassName(\n 'ltag__user-subscription-tag__response-message',\n );\n\n for (const notice of allNotices) {\n notice.classList.remove('hidden');\n notice.classList.add(`crayons-notice--${variant}`);\n notice.textContent = content;\n }\n\n // When a notice is shown, we hide the generic signed-in instructions\n toggleSignedInInstructionsUI(false);\n}\n\nfunction clearNotices() {\n // Since all user sub tags on the same article page perform the same action, all notices are kept in sync\n const allNotices = document.getElementsByClassName(\n 'ltag__user-subscription-tag__response-message',\n );\n\n for (const notice of allNotices) {\n notice.classList.add('hidden');\n }\n\n // Re-show the signed in instructions\n toggleSignedInInstructionsUI(true);\n}\n\nfunction toggleSignedInInstructionsUI(isVisible) {\n const signedInInstructions = document.querySelectorAll(\n '.ltag__user-subscription-tag__signed-in .ltag__user-subscription-tag__logged-in-text',\n );\n\n for (const instructions of signedInInstructions) {\n if (isVisible) {\n instructions.classList.remove('hidden');\n } else {\n instructions.classList.add('hidden');\n }\n }\n}\n\nfunction submitSubscription() {\n toggleSubmitButtonsState({ disabled: true, textContent: 'Submitting' });\n\n const articleId =\n document.getElementById('article-body')?.dataset?.articleId ?? null;\n\n const subscriber = userData();\n const body = JSON.stringify({\n user_subscription: {\n source_type: 'Article',\n source_id: articleId,\n subscriber_email: subscriber.email,\n },\n });\n\n return getCsrfToken()\n .then(sendFetch('user_subscriptions', body))\n .then((res) => res.json());\n}\n\nfunction fetchSubscriptionStatus() {\n const { articleId } = document.getElementById('article-body').dataset;\n\n const params = new URLSearchParams({\n source_type: 'Article',\n source_id: articleId,\n }).toString();\n\n const headers = {\n Accept: 'application/json',\n 'X-CSRF-Token': window.csrfToken,\n 'Content-Type': 'application/json',\n };\n\n return fetch(`/user_subscriptions/subscribed?${params}`, {\n method: 'GET',\n headers,\n credentials: 'same-origin',\n }).then((response) => {\n if (response.ok) {\n return response.json();\n }\n console.error(\n `Base data error: ${response.status} - ${response.statusText}`,\n );\n });\n}\n\nfunction showSubscribedNotices() {\n const { authorUsername } = document.getElementsByClassName(\n 'ltag__user-subscription-tag',\n )[0].dataset;\n\n updateNotices({\n variant: 'success',\n content: `You are now subscribed and may receive emails from ${authorUsername}`,\n });\n}\n\nfunction populateSubscriberProfileImage({\n profile_image_90: profileImageSrc,\n username,\n}) {\n document\n .querySelectorAll('.ltag__user-subscription-tag__subscriber-profile-image')\n .forEach((profileImage) => {\n profileImage.src = profileImageSrc;\n profileImage.alt = username;\n });\n}\n\n/**\n * Initializes the functionality of any user_subscription liquid tags in an article.\n *\n * An article may have more than one user_subscription liquid tag, but all instances complete the same action,\n * and are therefore kept in-step throughout any user interaction or update (i.e. the UI and behavior of all user_subscription\n * liquid tags in an article will always be the same).\n */\nexport async function initializeUserSubscriptionLiquidTagContent() {\n const allUserSubLiquidTags = document.getElementsByClassName(\n 'ltag__user-subscription-tag__container',\n );\n\n const { userStatus } = document.querySelector('body').dataset;\n if (userStatus === 'logged-out') {\n for (const liquidTag of allUserSubLiquidTags) {\n initSignedOutState(liquidTag);\n }\n return;\n }\n\n const { currentUser: user } = await getUserDataAndCsrfToken();\n const { apple_auth: isSubscriberAuthedWithApple } = user;\n\n // Setup the initial signed-in state without waiting on subscription status fetch\n for (const liquidTag of allUserSubLiquidTags) {\n initSignedInState(liquidTag, isSubscriberAuthedWithApple);\n }\n\n // Check if we need to refresh UI due to existing subscription\n populateSubscriberProfileImage(user);\n fetchSubscriptionStatus().then(({ is_subscribed: isSubscribed }) => {\n if (isSubscribed) {\n showSubscribedNotices();\n }\n for (const liquidTag of allUserSubLiquidTags) {\n toggleSubscribeActionUI({\n tagContainer: liquidTag,\n showSubscribeAction: !isSubscribed,\n appleAuth: isSubscriberAuthedWithApple,\n });\n }\n });\n}\n","import { h, render } from 'preact';\nimport ahoy from 'ahoy.js';\nimport { Snackbar, addSnackbarItem } from '../Snackbar';\nimport { addFullScreenModeControl } from '../utilities/codeFullscreenModeSwitcher';\nimport { initializeDropdown } from '../utilities/dropdownUtils';\nimport { embedGists } from '../utilities/gist';\nimport { initializeUserSubscriptionLiquidTagContent } from '../liquidTags/userSubscriptionLiquidTag';\nimport { trackCommentClicks } from '@utilities/ahoy/trackEvents';\nimport { isNativeAndroid, copyToClipboard } from '@utilities/runtime';\n\nconst animatedImages = document.querySelectorAll('[data-animated=\"true\"]');\nif (animatedImages.length > 0) {\n import('@utilities/animatedImageUtils').then(\n ({ initializePausableAnimatedImages }) => {\n initializePausableAnimatedImages(animatedImages);\n },\n );\n}\n\nconst fullscreenActionElements = document.getElementsByClassName(\n 'js-fullscreen-code-action',\n);\n\nif (fullscreenActionElements) {\n addFullScreenModeControl(fullscreenActionElements);\n}\n\n// The Snackbar for the article page\nconst snackZone = document.getElementById('snack-zone');\nif (snackZone) {\n render(, snackZone);\n}\n\n// eslint-disable-next-line no-restricted-globals\ntop.addSnackbarItem = addSnackbarItem;\n\nconst multiReactionDrawerTrigger = document.getElementById(\n 'reaction-drawer-trigger',\n);\n\nif (\n multiReactionDrawerTrigger &&\n multiReactionDrawerTrigger.dataset.initialized !== 'true'\n) {\n initializeDropdown({\n triggerElementId: 'reaction-drawer-trigger',\n dropdownContentId: 'reaction-drawer',\n });\n}\n\n// Dropdown accessibility\nfunction hideCopyLinkAnnouncerIfVisible() {\n document.getElementById('article-copy-link-announcer').hidden = true;\n}\n\n// Initialize the share options\nconst shareDropdownButton = document.getElementById('article-show-more-button');\n\nif (shareDropdownButton.dataset.initialized !== 'true') {\n if (isNativeAndroid('shareText')) {\n // Android native apps have enhanced sharing capabilities for Articles and don't use our standard dropdown\n shareDropdownButton.addEventListener('click', () =>\n AndroidBridge.shareText(location.href),\n );\n } else {\n const { closeDropdown } = initializeDropdown({\n triggerElementId: 'article-show-more-button',\n dropdownContentId: 'article-show-more-dropdown',\n onClose: hideCopyLinkAnnouncerIfVisible,\n });\n\n // We want to close the dropdown on link select (since they open in a new tab)\n document\n .querySelectorAll('#article-show-more-dropdown [href]')\n .forEach((link) => {\n link.addEventListener('click', (event) => {\n closeDropdown(event);\n });\n });\n }\n\n shareDropdownButton.dataset.initialized = 'true';\n}\n\n// Initialize the copy to clipboard functionality\nfunction showAnnouncer() {\n document.getElementById('article-copy-link-announcer').hidden = false;\n}\n\n// Temporary Ahoy Stats for displaying comments section either on page load or after scrolling\nfunction trackCommentsSectionDisplayed() {\n const callback = (entries, observer) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n ahoy.track('Comment section viewable', { page: location.href });\n observer.disconnect();\n }\n if (location.hash === '#comments') {\n //handle focus event on text area\n const element = document.getElementById('text-area');\n const event = new FocusEvent('focus');\n element.dispatchEvent(event);\n }\n });\n };\n\n const target = document.getElementById('comments');\n const observer = new IntersectionObserver(callback, {});\n observer.observe(target);\n}\n\nfunction copyArticleLink() {\n const postUrlValue = document\n .getElementById('copy-post-url-button')\n .getAttribute('data-postUrl');\n copyToClipboard(postUrlValue).then(() => {\n showAnnouncer();\n });\n}\ndocument\n .getElementById('copy-post-url-button')\n ?.addEventListener('click', copyArticleLink);\n\n// Comment Subscription\ngetCsrfToken().then(async () => {\n const { user = null, userStatus } = document.body.dataset;\n const root = document.getElementById('comment-subscription');\n const isLoggedIn = userStatus === 'logged-in';\n\n if (!root) {\n return;\n }\n try {\n const {\n getCommentSubscriptionStatus,\n setCommentSubscriptionStatus,\n CommentSubscription,\n } = await import('../CommentSubscription');\n\n const { articleId } = document.getElementById('article-body').dataset;\n\n let subscriptionType = 'not_subscribed';\n\n if (isLoggedIn && user !== null) {\n ({ config: subscriptionType } = await getCommentSubscriptionStatus(\n articleId,\n ));\n }\n\n const subscriptionRequestHandler = async (type) => {\n const message = await setCommentSubscriptionStatus(articleId, type);\n\n addSnackbarItem({ message, addCloseButton: true });\n };\n\n render(\n ,\n root,\n );\n } catch (e) {\n root.innerHTML =\n '

Unable to load Comment Subscription component.
Try refreshing the page.

';\n }\n});\n\nconst targetNode = document.querySelector('#comments');\ntargetNode && embedGists(targetNode);\n\ninitializeUserSubscriptionLiquidTagContent();\n// Temporary Ahoy Stats for comment section clicks on controls\ntrackCommentClicks('comments');\ntrackCommentsSectionDisplayed();\n","/**\n * This function returns a string combining the current Medium and OS\n * that represents the current Context where the app is running.\n *\n * @returns {String} \"Medium-OS\", for example \"Browser-Android\"\n */\nexport const currentContext = () => `${currentMedium()}-${currentOS()}`;\n\n/**\n * This function returns a string that represents the current Medium where\n * the app is currently running. The currently supported mediums are Browser,\n * and ForemWebView.\n *\n * @returns {String} One of the supported Mediums\n */\nexport const currentMedium = () =>\n /ForemWebView/i.test(navigator.userAgent) ? 'ForemWebView' : 'Browser';\n\n/**\n * This function returns a string that represents the current OS where the app\n * is currently running. The currently supported Operating Systems are\n * Windows, Linux, macOS, Android and iOS.\n *\n * @returns {String} One of the supported Operating Systems or 'Unsupported'\n */\nexport const currentOS = () => {\n const macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'];\n const windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];\n const iosPlatforms = ['iPhone', 'iPad', 'iPod'];\n\n if (macosPlatforms.includes(window.navigator.platform)) {\n return 'macOS';\n } else if (iosPlatforms.includes(window.navigator.platform)) {\n return 'iOS';\n } else if (windowsPlatforms.includes(window.navigator.platform)) {\n return 'Windows';\n } else if (/Android/i.test(window.navigator.userAgent)) {\n return 'Android';\n } else if (/Linux/i.test(window.navigator.platform)) {\n return 'Linux';\n }\n\n return 'Unsupported';\n};\n\n/**\n * Checks the device for iOS (webkit) native feature support\n *\n * @function isNativeIOS\n * @param {string} namespace Specifies support for a specific feature\n * (i.e. video, podcast, etc)\n * @returns {boolean} true if current environment support native features\n */\nexport const isNativeIOS = (namespace = null) => {\n const nativeCheck =\n /DEV-Native-ios|ForemWebView/i.test(navigator.userAgent) &&\n window &&\n window.webkit &&\n window.webkit.messageHandlers;\n\n let namespaceCheck = true;\n if (nativeCheck && namespace) {\n namespaceCheck = window.webkit.messageHandlers[namespace] != undefined;\n }\n\n return nativeCheck && namespaceCheck;\n};\n\n/**\n * Checks the device for Android native feature support\n *\n * @function isNativeAndroid\n * @param {string} namespace Specifies support for a specific feature\n * (i.e. videoMessage, podcastMessage, etc)\n * @returns {boolean} true if current environment support native features\n */\nexport const isNativeAndroid = (namespace = null) => {\n const nativeCheck =\n /DEV-Native-android|ForemWebView/i.test(navigator.userAgent) &&\n typeof AndroidBridge !== 'undefined';\n\n let namespaceCheck = true;\n if (nativeCheck && namespace) {\n namespaceCheck = AndroidBridge[namespace] != undefined;\n }\n\n return nativeCheck && namespaceCheck;\n};\n\n/**\n * This function copies text to clipboard taking in consideration all\n * supported platforms.\n *\n * @param {string} text to be copied to the clipboard\n *\n * @returns {Promise} Resolves when successful in copying to clipboard\n */\nexport const copyToClipboard = (text) => {\n return new Promise((resolve, reject) => {\n if (isNativeAndroid('copyToClipboard')) {\n AndroidBridge.copyToClipboard(text);\n resolve();\n } else if (navigator.clipboard != null) {\n navigator.clipboard\n .writeText(text)\n .then(() => {\n resolve();\n })\n .catch((e) => {\n reject(e);\n });\n } else {\n reject('Unable to copy the text. Try reloading the page');\n }\n });\n};\n\n/**\n * Returns true if the supplied KeyboardEvent includes the OS-specific\n * modifier key. For example, the Cmd key on Apple platforms or the Ctrl key\n * on others.\n *\n * @param {KeyboardEvent} The event to check for the OS-specific modifier key\n *\n * @returns {Boolean} true if the event was fired with the OS-specific\n * modifier key, false otherwise. Also returns false if\n * the event is not a KeyboardEvent.\n */\nexport const hasOSSpecificModifier = (event) => {\n if (!(event instanceof KeyboardEvent)) {\n return false;\n }\n\n if (navigator.userAgent.indexOf('Mac OS X') >= 0) {\n return event.metaKey;\n }\n return event.ctrlKey;\n};\n\n/**\n * Returns a string representation of the expected modifier key for the current OS.\n * This allows us to display correct shortcut key hints to users in the UI, and set up correct shortcut key bindings.\n *\n * @returns {string} either 'cmd' if on macOS, or 'ctrl' otherwise\n */\nexport const getOSKeyboardModifierKeyString = () =>\n currentOS() === 'macOS' ? 'cmd' : 'ctrl';\n\n/**\n * @returns {string} A string representing the locale as per the user's browser settings\n */\nexport const getCurrentLocale = () => navigator.language;\n","import { useState, useEffect } from 'preact/hooks';\n\n/**\n * Pre-defined breakpoints for width.\n *\n * Note: These were copied from _import.scss.\n */\nexport const BREAKPOINTS = Object.freeze({\n Small: 640,\n Medium: 768,\n Large: 1024,\n ExtraLarge: 1280,\n});\n\n/**\n * A custom Preact hook for evaluating whether or not a CSS media query is matched or not.\n *\n * @param {string} query The media query to evaluate.\n *\n * @returns {boolean} True if the media query is matched, false otherwise.\n *\n * @example\n * import { useMediaQuery } from '@components/useMediaQuery';\n *\n * function SomeComponent({ query }) {\n * const matchesBreakpoint = useMediaQuery(query);\n *\n * if (!matchesBreakpoint) {\n * return null;\n * }\n *\n * return \n * }\n */\nexport const useMediaQuery = (query) => {\n const mediaQuery = window.matchMedia(query);\n\n const [match, setMatch] = useState(!!mediaQuery.matches);\n\n useEffect(() => {\n const handler = () => {\n setMatch(!!mediaQuery.matches);\n };\n mediaQuery.addListener(handler);\n\n return () => mediaQuery.removeListener(handler);\n });\n\n return match;\n};\n"],"sourceRoot":""}