refactor: remove cn helper function from the editor package (#6217)

This commit is contained in:
Aaryan Khandelwal 2024-12-18 12:22:14 +05:30 committed by GitHub
parent ddd4b51b4e
commit 580c4b1930
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 123 additions and 131 deletions

View file

@ -57,7 +57,6 @@
"@tiptap/starter-kit": "^2.1.13",
"@tiptap/suggestion": "^2.0.13",
"class-variance-authority": "^0.7.0",
"clsx": "^1.2.1",
"highlight.js": "^11.8.0",
"jsx-dom-cjs": "^8.0.3",
"linkifyjs": "^4.1.3",
@ -66,7 +65,6 @@
"prosemirror-codemark": "^0.4.2",
"prosemirror-utils": "^1.2.2",
"react-moveable": "^0.54.2",
"tailwind-merge": "^1.14.0",
"tippy.js": "^6.3.7",
"tiptap-markdown": "^0.8.9",
"uuid": "^10.0.0",

View file

@ -1,9 +1,9 @@
import { FC, ReactNode } from "react";
import { Editor } from "@tiptap/react";
// plane utils
import { cn } from "@plane/utils";
// constants
import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config";
// helpers
import { cn } from "@/helpers/common";
// types
import { TDisplayConfig } from "@/types";

View file

@ -1,7 +1,7 @@
import { useCallback, useEffect, useRef, useState } from "react";
import tippy, { Instance } from "tippy.js";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// types
import { TAIHandler } from "@/types";

View file

@ -1,9 +1,9 @@
import { Editor } from "@tiptap/core";
import { AlignCenter, AlignLeft, AlignRight, LucideIcon } from "lucide-react";
// plane utils
import { cn } from "@plane/utils";
// components
import { TextAlignItem } from "@/components/menus";
// helpers
import { cn } from "@/helpers/common";
// types
import { TEditorCommands } from "@/types";

View file

@ -1,10 +1,11 @@
import { Dispatch, FC, SetStateAction } from "react";
import { Editor } from "@tiptap/react";
import { ALargeSmall, Ban } from "lucide-react";
// plane utils
import { cn } from "@plane/utils";
// constants
import { COLORS_LIST } from "@/constants/common";
// helpers
import { cn } from "@/helpers/common";
import { BackgroundColorItem, TextColorItem } from "../menu-items";
type Props = {

View file

@ -1,8 +1,10 @@
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useRef } from "react";
import { Editor } from "@tiptap/core";
import { Check, Link, Trash } from "lucide-react";
// plane utils
import { cn } from "@plane/utils";
// helpers
import { cn, isValidHttpUrl } from "@/helpers/common";
import { isValidHttpUrl } from "@/helpers/common";
import { setLinkEditor, unsetLinkEditor } from "@/helpers/editor-commands";
type Props = {

View file

@ -1,6 +1,8 @@
import { Dispatch, FC, SetStateAction } from "react";
import { Editor } from "@tiptap/react";
import { Check, ChevronDown } from "lucide-react";
// plane utils
import { cn } from "@plane/utils";
// components
import {
BulletListItem,
@ -17,8 +19,6 @@ import {
HeadingSixItem,
EditorMenuItem,
} from "@/components/menus";
// helpers
import { cn } from "@/helpers/common";
// types
import { TEditorCommands } from "@/types";

View file

@ -1,5 +1,7 @@
import { FC, useEffect, useState } from "react";
import { BubbleMenu, BubbleMenuProps, Editor, isNodeSelection } from "@tiptap/react";
// plane utils
import { cn } from "@plane/utils";
// components
import {
BoldItem,
@ -13,8 +15,6 @@ import {
} from "@/components/menus";
// extensions
import { isCellSelection } from "@/extensions/table/table/utilities/is-cell-selection";
// helpers
import { cn } from "@/helpers/common";
// local components
import { TextAlignmentSelector } from "./alignment-selector";

View file

@ -1,8 +1,8 @@
import { Ban, ChevronDown } from "lucide-react";
// plane utils
import { cn } from "@plane/utils";
// constants
import { COLORS_LIST } from "@/constants/common";
// helpers
import { cn } from "@/helpers/common";
type Props = {
disabled: boolean;

View file

@ -2,8 +2,8 @@
import { convertHexEmojiToDecimal } from "@plane/utils";
// plane ui
import { EmojiIconPicker, EmojiIconPickerTypes, Logo, TEmojiLogoProps } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// types
import { TCalloutBlockAttributes } from "./types";
// utils

View file

@ -8,8 +8,8 @@ import { common, createLowlight } from "lowlight";
import { CopyIcon, CheckIcon } from "lucide-react";
// ui
import { Tooltip } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// we just have ts support for now
const lowlight = createLowlight(common);

View file

@ -1,9 +1,9 @@
import React, { useRef, useState, useCallback, useLayoutEffect, useEffect } from "react";
import { NodeSelection } from "@tiptap/pm/state";
// plane utils
import { cn } from "@plane/utils";
// extensions
import { CustoBaseImageNodeViewProps, ImageToolbarRoot } from "@/extensions/custom-image";
// helpers
import { cn } from "@/helpers/common";
const MIN_SIZE = 100;

View file

@ -1,7 +1,7 @@
import { ChangeEvent, useCallback, useEffect, useMemo, useRef } from "react";
import { ImageIcon } from "lucide-react";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// hooks
import { useUploader, useDropZone, uploadFirstImageAndInsertRemaining } from "@/hooks/use-file-upload";
// extensions

View file

@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ExternalLink, Maximize, Minus, Plus, X } from "lucide-react";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
type Props = {
image: {

View file

@ -1,6 +1,6 @@
import { useState } from "react";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// components
import { ImageFullScreenAction } from "./full-screen";

View file

@ -5,8 +5,8 @@
// @ts-nocheck
import { useEffect, useState } from "react";
import { NodeViewWrapper } from "@tiptap/react";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// types
import { IMentionHighlight } from "@/types";

View file

@ -5,8 +5,8 @@ import { Editor } from "@tiptap/react";
import { v4 as uuidv4 } from "uuid";
// ui
import { Avatar } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// types
import { IMentionSuggestion } from "@/types";

View file

@ -1,5 +1,5 @@
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// types
import { ISlashCommandItem } from "@/types";

View file

@ -1,6 +1,6 @@
import { EditorState, Selection } from "@tiptap/pm/state";
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
// plane utils
import { cn } from "@plane/utils";
interface EditorClassNames {
noBorder?: boolean;
@ -18,10 +18,6 @@ export const getEditorClassNames = ({ noBorder, borderOnFocus, containerClassNam
containerClassName
);
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
// Helper function to find the parent node of a specific type
export function findParentNodeOfType(selection: Selection, typeName: string) {
let depth = selection.$anchor.depth;

View file

@ -1,6 +1,6 @@
import { EditorProps } from "@tiptap/pm/view";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
export type TCoreEditorProps = {
editorClassName: string;

View file

@ -1,6 +1,6 @@
import { EditorProps } from "@tiptap/pm/view";
// helpers
import { cn } from "@/helpers/common";
// plane utils
import { cn } from "@plane/utils";
// props
import { TCoreEditorProps } from "@/props";

View file

@ -15,8 +15,10 @@
"lint:errors": "eslint src --ext .ts,.tsx --quiet"
},
"dependencies": {
"clsx": "^2.1.1",
"isomorphic-dompurify": "^2.16.0",
"react": "^18.3.1"
"react": "^18.3.1",
"tailwind-merge": "^2.5.5"
},
"devDependencies": {
"@plane/eslint-config": "*",

View file

@ -0,0 +1,4 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));

View file

@ -1,3 +1,4 @@
export * from "./color";
export * from "./common";
export * from "./emoji";
export * from "./string";

View file

@ -1,7 +1,7 @@
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
//plane
import { cn } from "@plane/editor";
// plane utils
import { cn } from "@plane/utils";
// components
import { IssueEmojiReactions, IssueVotes } from "@/components/issues/reactions";
// hooks

View file

@ -4,10 +4,12 @@ import { MutableRefObject } from "react";
import { observer } from "mobx-react";
import Link from "next/link";
import { useParams, useSearchParams } from "next/navigation";
// plane
import { cn } from "@plane/editor";
// plane types
import { IIssueDisplayProperties } from "@plane/types";
// plane ui
import { Tooltip } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// components
import { WithDisplayPropertiesHOC } from "@/components/issues/issue-layouts/with-display-properties-HOC";
// helpers

View file

@ -4,10 +4,12 @@ import { useRef } from "react";
import { observer } from "mobx-react";
import Link from "next/link";
import { useParams, useSearchParams } from "next/navigation";
// types
import { cn } from "@plane/editor";
// plane types
import { IIssueDisplayProperties } from "@plane/types";
// plane ui
import { Tooltip } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// helpers
import { queryParamGenerator } from "@/helpers/query-param-generator";
// hooks

View file

@ -2,9 +2,10 @@
import { Fragment, MutableRefObject, forwardRef, useRef, useState } from "react";
import { observer } from "mobx-react";
import { cn } from "@plane/editor";
// plane
// plane types
import { IGroupByColumn, TIssueGroupByOptions, IIssueDisplayProperties, TPaginationData, TLoader } from "@plane/types";
// plane utils
import { cn } from "@plane/utils";
// hooks
import { useIntersectionObserver } from "@/hooks/use-intersection-observer";
//

View file

@ -2,11 +2,12 @@
import { observer } from "mobx-react";
import { Layers, Link, Paperclip } from "lucide-react";
// types
import { cn } from "@plane/editor";
// plane types
import { IIssueDisplayProperties } from "@plane/types";
// plane ui
import { Tooltip } from "@plane/ui";
// ui
// plane utils
import { cn } from "@plane/utils";
// components
import {
IssueBlockDate,

View file

@ -1,9 +1,10 @@
"use client";
import { observer } from "mobx-react";
// ui
import { cn } from "@plane/editor";
// plane ui
import { ContrastIcon, Tooltip } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
//hooks
import { useCycle } from "@/hooks/store/use-cycle";

View file

@ -3,9 +3,10 @@
import { observer } from "mobx-react";
// icons
import { LucideIcon, Users } from "lucide-react";
// ui
import { cn } from "@plane/editor";
// plane ui
import { Avatar, AvatarGroup } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// hooks
import { useMember } from "@/hooks/store/use-member";
//

View file

@ -1,9 +1,10 @@
"use client";
import { observer } from "mobx-react";
// planes
import { cn } from "@plane/editor";
// plane ui
import { DiceIcon, Tooltip } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// hooks
import { useModule } from "@/hooks/store/use-module";

View file

@ -1,9 +1,10 @@
"use client";
import { observer } from "mobx-react";
// ui
import { cn } from "@plane/editor";
// plane ui
import { StateGroupIcon, Tooltip } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
//hooks
import { useStates } from "@/hooks/store";

View file

@ -1,6 +1,6 @@
import { Plus } from "lucide-react";
// Plane
import { cn } from "@plane/editor";
// plane utils
import { cn } from "@plane/utils";
type Props = {
workspaceSlug: string;

View file

@ -1,6 +1,8 @@
import { LucideIcon } from "lucide-react";
import { cn } from "@plane/editor";
// plane ui
import { Tooltip } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
type Props = {
onChange: (value: number) => void;

View file

@ -1,9 +1,10 @@
import { useCallback, useMemo } from "react";
import { observer } from "mobx-react";
import { Check } from "lucide-react";
// plane packages
import { cn } from "@plane/editor";
// plane ui
import { Dropdown } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// constants
import { EIssueLayoutTypes, ISSUE_LAYOUT_MAP } from "@/constants/issue";

View file

@ -3,8 +3,9 @@
import { observer } from "mobx-react";
import { LucideIcon, Users } from "lucide-react";
// plane ui
import { cn } from "@plane/editor";
import { Avatar, AvatarGroup } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// helpers
import { getFileURL } from "@/helpers/file.helper";
// hooks

View file

@ -1,7 +1,7 @@
import { FC } from "react";
import { observer } from "mobx-react";
// Plane
import { cn } from "@plane/editor";
// plane utils
import { cn } from "@plane/utils";
// hooks
import { useTimeLineChartStore } from "@/hooks/use-timeline-chart";
//

View file

@ -1,7 +1,7 @@
import { FC } from "react";
import { observer } from "mobx-react";
// Plane
import { cn } from "@plane/editor";
// plane utils
import { cn } from "@plane/utils";
// hooks
import { useTimeLineChartStore } from "@/hooks/use-timeline-chart";
//

View file

@ -1,7 +1,7 @@
import { useState } from "react";
import { observer } from "mobx-react";
// Plane
import { cn } from "@plane/editor";
// plane utils
import { cn } from "@plane/utils";
//helpers
import { renderFormattedDate } from "@/helpers/date-time.helper";
//hooks

View file

@ -1,7 +1,7 @@
import { useState } from "react";
import { observer } from "mobx-react";
// Plane
import { cn } from "@plane/editor";
// plane utils
import { cn } from "@plane/utils";
//helpers
import { renderFormattedDate } from "@/helpers/date-time.helper";
//hooks

View file

@ -1,8 +1,10 @@
import { FC } from "react";
import { ChevronDown, ListFilter } from "lucide-react";
// components
import { cn } from "@plane/editor";
// plane ui
import { getButtonStyling } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// components
import { InboxIssueFilterSelection, InboxIssueOrderByDropdown } from "@/components/inbox/inbox-filter";
import { FiltersDropdown } from "@/components/issues";
import useSize from "@/hooks/use-window-size";

View file

@ -4,8 +4,7 @@ import { MutableRefObject, useEffect, useRef, useState } from "react";
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import { observer } from "mobx-react";
import { cn } from "@plane/editor";
// plane packages
// plane ui
import {
IGroupByColumn,
TIssueMap,
@ -16,6 +15,8 @@ import {
TIssueKanbanFilters,
} from "@plane/types";
import { Row, setToast, TOAST_TYPE } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// components
import { ListLoaderItemRow } from "@/components/ui";
// constants

View file

@ -3,10 +3,9 @@
import React, { FC, useCallback, useEffect, useRef, useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// icons
import { ListFilter, Search, X } from "lucide-react";
// editor
import { cn } from "@plane/editor";
// plane utils
import { cn } from "@plane/utils";
// plane helpers
import { useOutsideClickDetector } from "@plane/hooks";
// types

View file

@ -1,9 +1,10 @@
import { ChangeEvent } from "react";
import { Controller, useFormContext, UseFormSetValue } from "react-hook-form";
import { Info } from "lucide-react";
import { cn } from "@plane/editor";
// ui
// plane ui
import { Input, TextArea, Tooltip } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// constants
import { ETabIndices } from "@/constants/tab-indices";
// helpers

View file

@ -2,9 +2,10 @@ import { useCallback } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { ListFilter } from "lucide-react";
// types
import { cn } from "@plane/editor";
// plane types
import { TProjectFilters } from "@plane/types";
// plane utils
import { cn } from "@plane/utils";
// components
import { FiltersDropdown } from "@/components/issues";
import { ProjectFiltersSelection, ProjectOrderByDropdown } from "@/components/project";

View file

@ -1,7 +1,9 @@
import { forwardRef } from "react";
import range from "lodash/range";
import { cn } from "@plane/editor";
// plane ui
import { ContentWrapper } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
export const KanbanIssueBlockLoader = forwardRef<HTMLSpanElement, { cardHeight?: number; shouldAnimate?: boolean }>(
({ cardHeight = 100, shouldAnimate = true }, ref) => (

View file

@ -1,7 +1,9 @@
import { Fragment, forwardRef } from "react";
import range from "lodash/range";
import { cn } from "@plane/editor";
// plane ui
import { Row } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
import { getRandomInt, getRandomLength } from "../utils";
export const ListLoaderItemRow = forwardRef<

View file

@ -1,5 +1,6 @@
// plane utils
import { cn } from "@plane/utils";
// helpers
import { cn } from "@plane/editor";
import { getFileURL } from "@/helpers/file.helper";
type Props = {

View file

@ -5400,11 +5400,6 @@ clone@^2.1.2:
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==
clsx@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
clsx@^2.0.0, clsx@^2.1.0, clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
@ -11271,16 +11266,7 @@ streamx@^2.15.0, streamx@^2.20.0:
optionalDependencies:
bare-events "^2.2.0"
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -11368,14 +11354,7 @@ string_decoder@^1.1.1, string_decoder@^1.3.0:
dependencies:
safe-buffer "~5.2.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@ -11516,12 +11495,7 @@ tabbable@^6.0.0:
resolved "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz"
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
tailwind-merge@^1.14.0:
version "1.14.0"
resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz"
integrity sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==
tailwind-merge@^2.0.0:
tailwind-merge@^2.0.0, tailwind-merge@^2.5.5:
version "2.5.5"
resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz"
integrity sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA==
@ -12631,16 +12605,7 @@ word-wrap@^1.2.5:
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==