import { Jsmin } from '@mingoo/jsmin'
import { FontAwesomeIconProps } from '@fortawesome/react-fontawesome'
import { IconDefinition } from "@fortawesome/fontawesome-common-types"
import * as FontawesomeCore from '@fortawesome/fontawesome-svg-core'

import React from 'react'
import ReactDOM from 'react-dom'
import * as ReactRouterDOM from 'react-router-dom'

import {
  ReactElement,
  Device,
  Browser
} from './_'
import {
  TagProps
} from './property'

export namespace config {
  export interface Methods {
    sessionUID: string
    appRootID: string
    appRoot: HTMLElement
    themeColor: TagProps.ThemeColor
    darkMode: TagProps.DarkMode
    roundness: TagProps.Roundness
    device: {
      deviceIs: Device
      browserIs: Browser
      isBreakpoint(): boolean
      isPhonepoint(): boolean
      isSystemDarkmode(): boolean
      isPhone: boolean
      isTouchDevice: boolean
      isIOS: boolean
    }
    update: {
      themeColor( value: TagProps.ThemeColor ): void
      darkMode( value: TagProps.DarkMode ): void
      roundness( value: TagProps.Roundness ): void
    }
    variables: {
      darkmodeColors: {
        light: string
        dark: string
        dim: string
        auto(): string
      }
      themeColors: {
        [ key in TagProps.ThemeColor ]: {
          alfa( alfa?: number ): string
          isBrand: boolean
          isAvocado: boolean
        }
      }
    }
    readExtraCDN( url: string ): Promise<boolean>
  }
}
export namespace global {
  export type LaunchRootInput = {
    baseElement?: HTMLElement
  }
  export type LaunchReactApplicationInput = {
    baseElement?: HTMLElement | string
    reactElement: ReactElement
    nonRouter?: boolean
    isRoot?: boolean
    appearances?: {
      roundness?: TagProps.Roundness
      themeColor?: TagProps.ThemeColor
      darkMode?: TagProps.DarkMode
    }
  }
  export type useStoreParams = {
    set( params: {
      key: string
      value: any
      privateKey?: string
    } ): boolean
    update( params: {
      key: string
      value: any
      privateKey?: string
    } ): boolean
    get( key: string,privateKey?: string ): any
    delete( key: string,privateKey?: string ): boolean
  }
  export type useRecycleParams = {
    set( key: string ): string
    do( key: string ): void
  }
  export type PageTransitParams = {
    open( url: string ): void
    pushSync( url: string ): void
    pushAsync( url: string ): void
    push( url: string,newTab?: boolean ): void
    back(): void
  }
  export namespace StyleConverter {
    export type ReadStyleSet = {
      <T>( params: T ): T
    }
    export type ToClassName = {
      <T>( params: T ): T
    }
  }

  export interface Methods {
    React: typeof React
    ReactDOM: typeof ReactDOM
    ReactRouterDOM: typeof ReactRouterDOM
    StyleConverter: {
      ReadStyleSet: StyleConverter.ReadStyleSet
      ToClassName: StyleConverter.ToClassName
    }

    pageTransit: PageTransitParams
    useStore: global.useStoreParams
    useRecycle: global.useRecycleParams
    LaunchRoot( params: global.LaunchRootInput ): void
    LaunchReactApplication( params: global.LaunchReactApplicationInput ): void
  }
}
export namespace atoms {
  export type BoxInput = TagProps.BasicElement & {
    children?: ReactElement
  } & React.HTMLAttributes<HTMLDivElement>
  export type SpanProps = TagProps.BasicElement & {
    children?: ReactElement
  } & React.HTMLAttributes<HTMLSpanElement>
  export type ParagraphProps = TagProps.BasicElement & {
    children?: ReactElement
  } & React.HTMLAttributes<HTMLParagraphElement>
  export type FlexProps = TagProps.BasicElement & {
    children?: ReactElement
  } & React.HTMLAttributes<HTMLDivElement>

  export type GridProps = TagProps.BasicElement & {
    children: ReactElement

    onClick?: {
      ( event: React.MouseEvent<HTMLDivElement,MouseEvent> ): void
    }
  } & React.HTMLAttributes<HTMLDivElement>
  export namespace FAI {
    export type Method = React.FC<FAIParams> & Shortcuts
    export type FAIParams = TagProps.BasicElement & {
      icon: FontawesomeCore.IconProp | IconDefinition
      iconParams?: Omit<FontAwesomeIconProps,'icon'>
    }
    export type Shortcuts = {
      [ key in ShortCutNames ]: React.FC<Omit<FAIParams,'icon'>>
    }
    export type ShortCutNames =
      'User' | 'Times' |

      'AngleRight' | 'AngleLeft' | 'AngleUp' | 'AngleDown' |
      'ChevronLeft' | 'ChevronRight' | 'ChevronUp' | 'ChevronDown' |
      'CaretLeft' | 'CaretRight' | 'CaretUp' | 'CaretDown' |
      'ArrowLeft' | 'ArrowRight' | 'ArrowUp' | 'ArrowDown' |

      'Rotate' | 'Redo' |
      'Check' | 'CheckCircle' |
      'Question' | 'QuestionCircle' |
      'Exclamation' | 'ExclamationTriangle' |
      'Home' | 'Share' |
      'Search' | 'YenSign' | 'Heart' | 'Star' |
      'Edit' | 'Pen' | 'Copy' | 'File' |
      'TrashAlt' | 'Bars' | 'Download' |
      'Link' | 'LinkSlash' | 'ExternalLinkAlt' |
      'Gear' |
      'Plus' | 'Minus' |
      'EllipsisH' | 'EllipsisV' |
      'PaperPlane' |
      'Image'
  }
  export namespace Image {
    export type Methods = React.FC<CompInput> & DefaultImages
    export type CompInput = TagProps.BasicElement & {
      src: string
      alt?: string
      showExpand?: boolean | string
    } & React.HTMLAttributes<HTMLImageElement>

    export type DefaultImages = {
      uri: {
        mingooIcon: string
        comunIcon: string
        comunIconClear: string
        defaultIcon( type:
          'image' |
          'object' |
          'user' |
          'group' |
          'store'
        ): string
      }

    }
  }
  export namespace Logos {
    export type Methods = {
      Icon: ( params: Params ) => JSX.Element
      Title: ( params: Params ) => JSX.Element

      Brands: {
        MingooIcon: ( params: DefaultLogo ) => JSX.Element
        MingooTitle: ( params: DefaultLogo ) => JSX.Element
        MingooLogoH: ( params: DefaultLogo ) => JSX.Element
        MingooLogoV: ( params: DefaultLogo ) => JSX.Element

        ComunIcon: ( params: DefaultLogo ) => JSX.Element
        ComunTitle: ( params: DefaultLogo ) => JSX.Element
        ComunLogoH: ( params: DefaultLogo ) => JSX.Element
        ComunLogoV: ( params: DefaultLogo ) => JSX.Element

        Google: ( params: DefaultLogo ) => JSX.Element
        Facebook: ( params: DefaultLogo ) => JSX.Element
        Twitter: ( params: DefaultLogo ) => JSX.Element
        LINE: ( params: DefaultLogo ) => JSX.Element
      }
    }
    export type Params = TagProps.BasicElement & {
      size?: 'S' | 'R' | 'L' | '2L' | '3L'
      color?: 'normal' | 'white'
      children?: ReactElement | React.FC<any>
    }
    export type DefaultLogo = TagProps.BasicElement & {
      size?: 'S' | 'R' | 'L' | '2L' | '3L'
      color?: 'normal' | 'white'
    }
  }
  export type PlaceholderParams = atoms.BoxInput & {
    color?: 'cloud' | 'white'
  }
  export type Methods = {
    Box: React.FC<atoms.BoxInput>

    Flex: React.FC<atoms.FlexProps>
    FlexBr: React.FC<TagProps.Params>

    Placeholder: React.FC<PlaceholderParams>

    Grid: React.FC<atoms.GridProps>

    FAI: FAI.Method

    Span: React.FC<atoms.SpanProps>
    Paragraph: React.FC<atoms.ParagraphProps>
    Img: atoms.Image.Methods

    Logo: Logos.Methods
  }
}
export namespace mols {
  export namespace Accordion {
    export type Params = {
      defaultOpen?: boolean
      override?: boolean
      accordionID?: string
      slideAnimation?: 'none' | 'fast' | 'slow'
      children: ReactElement
      onToggleEvent?: {
        ( open: boolean ): void
      }
    } & atoms.BoxInput
    export type FNParams = {
      fn: {
        open( accordionID: string ): void
        close( accordionID: string ): void
        toggle( accordionID: string ): void
      }
    }
    export type SetParams = React.FC<Params> & FNParams
  }
  export namespace List {
    export type Params = TagProps.BasicElement & {
      rowStyles?: TagProps.Params
      rows: RowsParams[]
    }
    export type RowsParams = {
      children: ReactElement
    } & TagProps.BasicElement
  }
  export type LinkifyTextProps = {
    text: string
    placeholder?: ReactElement
  }

  export type Methods = {
    List: React.FC<mols.List.Params>
    Accordion: mols.Accordion.SetParams
    LinkifyText: React.FC<mols.LinkifyTextProps>
    Text: {
      NowrapSpan: React.FC<atoms.SpanProps>
      Title: React.FC<atoms.BoxInput>
      SubTitle: React.FC<atoms.BoxInput>
      ThirdTitle: React.FC<atoms.BoxInput>
      Paragraph: React.FC<atoms.BoxInput>
      Normal: React.FC<atoms.BoxInput>
      Description: React.FC<atoms.BoxInput>
      Supplement: React.FC<atoms.BoxInput>
    }
    Column: React.FC<atoms.FlexProps>
    Row: {
      Center: React.FC<atoms.FlexProps>
      Left: React.FC<atoms.FlexProps>
      Right: React.FC<atoms.FlexProps>
      Separate: React.FC<atoms.FlexProps>
    }
  }
}
export namespace orgs {
  export type Methods = {}
}
export namespace temps {
  export type Methods = {
  }
}
export namespace fn {
  export namespace Layout {
    export type Methods = {
      PageViewController: React.FC<PageViewController.Params>
      TabBar: React.FC<TabBar.Params>
      Plate: React.FC<Plate.Params>
      SwipeView: React.FC<SwipeView.Params>

      PageRouter: React.FC<PageRouter.RouterProps>

      PageNotFound: React.FC<{}>

      RootViewController: RootViewController.Methods
    }
    export namespace PageViewController {
      export type Params = {
        viewIndex: number
        views: ReactElement[]
        wrapper?: {
          ( view: ReactElement ): ReactElement
        }
      }
    }
    export namespace TabBar {
      export type Params = {
        tabIndex: number
        tabs: ReactElement[]
        onTabChange?: {
          ( index: number ): void
        }

        componentDidMount?: {
          (): void
        }
      } & TagProps.BasicElement
    }
    export namespace Plate {
      export type Params = {
        size?: 'XS' | 'S' | 'R' | 'L' | 'XL' | 'MAX'
      } & atoms.BoxInput
    }
    export namespace SwipeView {
      export type Params = TagProps.BasicElement & {
        slideIndex?: number
        slides: ReactElement[]
        wrapper?: {
          ( slide: ReactElement ): ReactElement
        }
        options?: {
          onSlideCallback?: {
            ( index: number ): void
          }
          visibilitySurroundSlide?: boolean
          autoSwipeSeconds?: number
          loop?: boolean
          disableMousedrag?: boolean
          disableTouch?: boolean
        }
      }
    }
    export namespace PageRouter {
      export type RoutesProps = {
        path: string
        content: ReactElement
      }
      export type Callbacks = {
        beforeCallBack?: {
          ( pathName: string ): void
        }
        afterCallBack?: {
          ( pathName: string ): void
        }
        afterFirstCallBack?: {
          ( pathName: string ): void
        }
      }
      export type RoutesSwitchProps = {
        routes: RoutesProps[]
      } & Callbacks
      export type RouterProps = {
        pages: RoutesProps[]
      } & Callbacks
    }
    export namespace RootViewController {
      export type Methods = {
        Base: React.FC<RootViewController.BaseParams>
        TopNavigation: React.FC<atoms.FlexProps>
        SideNavigation: React.FC<atoms.FlexProps & {
          baseStyles?: TagProps.Params
        }>
        FooterNavigation: React.FC<atoms.FlexProps & {
          baseStyles?: TagProps.Params
        }>
        Comps: {
          Button: React.FC<ButtonParams>
          Title: React.FC<atoms.BoxInput>
          Bar: React.FC<atoms.BoxInput>
        }
        fn: FNs
      }
      export type BaseParams = atoms.BoxInput & {
        topNavigation?: ReactElement
        sideNavigation?: ReactElement
        footerNavigation?: ReactElement
      }
      export type ButtonParams = Buttons.ButtonInput & Buttons.Tones.Clear & {
        uri?: string
        uriGroup?: ( string | RegExp ) | ( string | RegExp )[]
      }
      export type FNs = {
        updateCSSProperty: {
          topNav(): void
          footer(): void
          reset(): void
        }
      }
    }
  }
  export namespace Tables {
    export type Methods = {
      Comps: CompsMethods

      Normal: ( props: Normal.Params ) => JSX.Element
      Data: Data.Methods
      Drag: ( props: Drag.Params ) => JSX.Element
      Spread: () => JSX.Element
    }
    export type CompsMethods = {
      Table: React.FC<TableParams>
      Head: React.FC<TableHeadParams>
      Body: React.FC<TableBodyParams>
      Row: React.FC<TRParams>

      TH: React.FC<TableCellParams>
      TD: React.FC<TableCellParams>
      RightIndicator: Uni.CellParams
    }
    export type DataCompsMethods = {
      Search: any
      Info: any
      Paging: any
    }
    export type customTableHTMLAttributes<T> = Omit<React.TableHTMLAttributes<T>,'border'>
    export type TableParams = TagProps.BasicElement & customTableHTMLAttributes<HTMLTableElement>
    export type TableHeadParams = TagProps.BasicElement & customTableHTMLAttributes<HTMLTableSectionElement>
    export type TableBodyParams = TagProps.BasicElement & customTableHTMLAttributes<HTMLTableSectionElement>
    export type TRParams = TagProps.BasicElement & React.HTMLAttributes<HTMLTableRowElement>
    export type TableCellParams = TagProps.BasicElement & React.ThHTMLAttributes<HTMLTableCellElement>
    export type Types = 'normal' | 'data' | 'drag' | 'spread'
    export type Tones = 'border' | 'cellBorder' | 'rowBorder' | 'plain' | 'auto'
    export type OnRowClick = {
      ( rowIDOrIndex: any,event: React.MouseEvent<HTMLTableRowElement,MouseEvent> ): void
    }
    export type StylesCallbackInput = {
      top: boolean
      bottom: boolean
      left: boolean
      right: boolean
      rowIndex: number
      colIndex: number
      isHeader: boolean
      isBody: boolean
    }
    export namespace Uni {
      export type CellParams = TableCellParams & {
        type?: 'th' | 'td'
      }
      export type Params = {
        tableID?: string
        tone?: Tones
        colLength: number
        cellStyles?: TagProps.Params
        cellClassName?: string
        cellStylesCallback?: {
          ( params: StylesCallbackInput ): TagProps.Params
        }

        className?: string
      } & TagProps.Params
    }
    export namespace Normal {
      export type CellParams = Uni.CellParams
      export type HeadRowParams = CellParams[]
      export type BodyRowParams = CellParams[] & {
        rowID?: string | number
      }
      export type Params = Uni.Params & {
        head: HeadRowParams | false
        rows: BodyRowParams[]

        onRowClick?: OnRowClick
      }
    }
    export namespace Drag {
      export type CellParams = Uni.CellParams
      export type HeadRowParams = CellParams[]
      export type BodyRowParams = CellParams[] & {
        rowID?: any
      }
      export type Params = Uni.Params & {
        head: HeadRowParams | false
        rows: BodyRowParams[]

        onOrderChanged: {
          ( orderList: any[] ): void
        }
      }
    }
    export namespace Data {
      export type CellParams = TableCellParams & {
        type?: 'th' | 'td'
        data: string | number
        option?: any
        orderIndex?: string | number
      }
      export type HeadRowParams = CellParams[]
      export type BodyRowParams = Array<CellParams> & ArrayObjectParams
      export type ArrayObjectParams = {
        rowID?: any
        __sys4SearchKey?: string
        checked?: boolean
        filtered?: boolean
        currentPage?: boolean
      }
      export type Params = Uni.Params & {
        tableID?: string
        head: HeadRowParams
        rows: BodyRowParams[]
        onRowClick?: OnRowClick

        eventID?: string
        checker?: boolean
        searchKeyword?: string
        filter?: boolean | boolean[]
        order?: boolean | boolean[]
        defaultOrder?: OrderParams
        pageRowLength: number
        noRecords?: ReactElement

        onOrderChanged?: {
          ( order: OrderParams ): void
        }
      }
      export type Methods = {
        ( props: Data.Params ): JSX.Element
      } & FNs & Comps
      export type FNs = {
        __memoryID: string
        useStatus( tableID: string ): useStatusOutput
        getRowData( tableID: string ): BodyRowParams[]
        setPageIndex( tableID: string,pageIndex: number ): void
        setRowLength( tableID: string,rowLength: number ): void
        setSearchKeyword( tableID: string,keyword: string ): void
      }
      export type Comps = {
        SearchInput: React.FC<{ tableID: string }>
        Info: React.FC<{ tableID: string }>
        Paging: React.FC<{ tableID: string }>
        RowLength: React.FC<{
          tableID: string
          lengthSelect: number[]
        }>
      }
      export type useStatusOutput = {
        tableComponentDidMount: boolean
        totalRows: number
        pageRows: number
        filteredRows: number
        searchKeyword: string
        filter: {
          enabled: boolean
          column: boolean[]
          current: ( string[] )[]
        }
        order: {
          enabled: boolean
          column: boolean[]
          current: fn.Tables.Data.OrderParams
        }
        paging: {
          rowLength: number
          pageLength: number
          currentPageIndex: number
        }
      }
      export type FilterColumnsProps = {
        index: number
        keyword: string
        enabled: boolean
      }[]
      export type OrderParams = [ number,'ASC' | 'DESC' ]
    }
    export namespace Spread {

    }
  }
  export namespace Input {
    export type Methods = {
      Plain: React.FC<TagProps.Params & React.InputHTMLAttributes<HTMLInputElement>>
      Hidden: ( params: Hidden.PlainParams ) => JSX.Element
      Text: Text.Methods
      TextArea: ( params: TextArea.PlainParams ) => JSX.Element
      Contenteditable: ( params: Contenteditable.PlainParams ) => JSX.Element
      DigitCharacters: ( params: DigitCharacters.PlainParams ) => JSX.Element
      Time: Time.Methods
      Select: ( params: Select.PlainParams ) => JSX.Element
      RichSelect: ( params: RichSelect.PlainParams ) => JSX.Element

      Radio: ( props: List.PlainParams ) => JSX.Element
      Checkbox: ( props: List.PlainParams ) => JSX.Element
      Checker: ( params: Checker.PlainParams ) => JSX.Element

      Chips: Chips.Methods
      Search: ( params: Search.PlainParams ) => JSX.Element
      File: Filer.Methods
      Slider: ( params: Slider.PlainParams ) => JSX.Element
      Switch: ( params: Switch.PlainParams ) => JSX.Element

      Segmented: Segmented.Types

      Comps: {
        RequiredSign: React.FC<atoms.SpanProps>
        RequiredShortSign: React.FC<atoms.SpanProps>
        OmitSign: React.FC<atoms.SpanProps>
        LeftIndicator: React.FC<IndicatorParams>
        RightIndicator: React.FC<IndicatorParams>
        LeftIcon: React.FC<IndicatorParams>
        RightIcon: React.FC<IndicatorParams>
      }
    }
    export type WrapperParams = atoms.BoxInput & {
      label?: ReactElement
      labelStyles?: TagProps.Params
      required?: boolean | 'plain' | 'omit'
    }
    export type UniParams = {
      name?: string
      form?: string

      status_id?: string
      componentID?: string

      override?: 'force' | 'beforeModified' | 'never'

      required?: boolean

      enableFormSubmit?: boolean

      checkValidationAtFirst?: boolean
      onValidate?: Validation.OnValidate
      onUpdateValue?: OnUpdateValue
      onUpdateValidValue?: OnUpdateValue
    }
    export type CoreParams = UniParams & {
      className?: string
      wrapStyles?: TagProps.Params
    } & TagProps.Params
    export type OnUpdateValue = {
      ( data: {
        value: any
        componentID: string
        storeData?: plainObject
        eventType: Validation.EventType
      } ): void
    }
    export type BoxTone = 'border' | 'cloud' | 'bottomBorder' | 'plain'
    export namespace Hidden {
      export type PlainParams = React.DOMAttributes<HTMLInputElement> & {
        componentID?: string
        name?: string
        form?: string

        enableFormSubmit?: boolean

        id?: string
        value?: string | number | plainObject
      }
    }
    export namespace Text {
      export type Methods = {
        Validate( value: any,restrict: Restrict ): {
          ok: boolean
          body: ReactElement
        }
        Normal: ( props: OriginParams ) => JSX.Element
        Katakana: ( props: OriginParams ) => JSX.Element
        HankakuKatakana: ( props: OriginParams ) => JSX.Element
        Number: ( props: PlainParams ) => JSX.Element
        DigitNumber: ( props: PlainParams ) => JSX.Element
        Tel: ( props: PlainParams ) => JSX.Element
        CreditCard: ( props: PlainParams ) => JSX.Element
        Email: ( props: PlainParams ) => JSX.Element
        Url: ( props: PlainParams ) => JSX.Element
        Postal: ( props: PlainParams ) => JSX.Element
        Password: ( props: PlainParams ) => JSX.Element
        Money: {
          JPY: ( props: PlainParams ) => JSX.Element
        }
      }
      export type Restrict = 'text' | 'katakana' | 'hankaku.katakana' | 'number' | 'digitNumber' | 'tel' | 'email' | 'url' | 'fileName' | 'password' | 'postal' | 'creditCard'
      export type PlainParams = CoreParams & React.DOMAttributes<HTMLInputElement> & {
        tone?: BoxTone

        tabIndex?: number
        id?: string

        disabled?: boolean

        min?: number | null
        max?: number | null
        maxLength?: number | null

        autoComplete?: 'off' | 'none' | string
        autoCapitalize?: 'off' | 'none' | string

        clearButton?: boolean

        value?: string | number

        placeholder?: string

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false
        leftIcon?: ReactElement | false
        rightIcon?: ReactElement | false
      }
      export type OriginParams = PlainParams & {
        restrict?: Restrict
      }
    }
    export namespace TextArea {
      export type PlainParams = CoreParams & React.TextareaHTMLAttributes<HTMLTextAreaElement> & {
        tone?: BoxTone

        tabIndex?: number
        id?: string

        disabled?: boolean


        value?: string | number

        placeholder?: string

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false
        leftIcon?: ReactElement | false
        rightIcon?: ReactElement | false
      }
    }
    export namespace Contenteditable {
      export type PlainParams = CoreParams & React.TextareaHTMLAttributes<HTMLDivElement> & {
        tone?: BoxTone

        tabIndex?: number
        id?: string

        children?: string

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false
        leftIcon?: ReactElement | false
        rightIcon?: ReactElement | false
      }
    }
    export namespace DigitCharacters {
      export type PlainParams = CoreParams & React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>,HTMLInputElement> & {
        tone?: BoxTone

        combineInput?: boolean
        digits: number
        numericOnly?: boolean

        tabIndex?: number
        id?: string


        value?: string | number

        listStyles?: TagProps.Params
      }
    }
    export namespace Time {
      export type Methods = {
        Clock: ( props: PlainParams ) => JSX.Element
        Date: ( props: PlainParams ) => JSX.Element
        Week: ( props: PlainParams ) => JSX.Element
        Month: ( props: PlainParams ) => JSX.Element
        Year: ( props: PlainParams ) => JSX.Element
        DateWareki: ( props: DateWarekiParams ) => JSX.Element
        Periods: {
          Date: ( props: PeriodParams ) => JSX.Element
          Month: ( props: PeriodParams ) => JSX.Element
        }
        fn: FN
      }
      export type FN = {
        picker: {
          launch( params: PickerParams & Omit<Tooltips.Params,'content'> ): void
          remove( tipsID: string ): void
        }
      }
      export type Era = 'clock' | 'year' | 'meiji' | 'taisho' | 'shouwa' | 'heisei' | 'reiwa'
      export type Restrict = 'clock' | 'date' | 'week' | 'month' | 'year' | 'dates' | 'months' | 'dateWareki'
      export type PlainParams = CoreParams & React.DOMAttributes<HTMLInputElement> & {
        tone?: BoxTone

        tabIndex?: number
        id?: string

        disabled?: boolean


        value?: string | [ string,string ]
        min?: string
        max?: string

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false
      }
      export type OriginParams = PlainParams & {
        restrict: Restrict
        era?: Era
      }
      export type DateWarekiParams = PlainParams & {
        value?: string
        defaultEra?: 'year' | 'wareki'
      }
      export type PeriodParams = Omit<PlainParams,'value'> & {
        value?: [ string,string ]
      }
      export type RangeProps = {
        type: 'hour' | 'minute' | 'date' | 'month' | 'year' | 'week' | 'dateWareki'
        from: number
        length: number
        region?: number
      }
      export type PickerParams = {
        tipsID?: string
        restrict: Restrict
        defaultValue: string | string[]
        era?: Era
        min?: string
        max?: string
        onValueUpdate( value: string | [ string,string ],era: Era ): void
      }
    }
    export namespace Select {
      export type PlainParams = CoreParams & React.DOMAttributes<HTMLSelectElement> & {
        tone?: BoxTone

        tabIndex?: number

        id?: string

        disabled?: boolean


        value?: ValueProps
        options: OptionProps[]

        placeholder?: string

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false
        leftIcon?: ReactElement | false
        rightIcon?: ReactElement | false

        enableUnSelected?: boolean

        rightIconStyles?: TagProps.Params

      }
      export type ValueProps = string | number | boolean | plainObject | void | null
      export type OptionProps = {
        value: ValueProps
        label: string
        displayLabel?: ReactElement
      }
    }
    export namespace RichSelect {
      export type PlainParams = CoreParams & React.DOMAttributes<HTMLInputElement> & {
        tone?: BoxTone

        tabIndex?: number

        id?: string

        disabled?: boolean

        value?: ValueProps
        options: OptionProps[]

        placeholder?: string

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false
        leftIcon?: ReactElement | false
        rightIcon?: ReactElement | false

        enableUnSelected?: boolean

        rightIconStyles?: TagProps.Params

        cellStyles?: TagProps.Params
        sheetStyles?: TagProps.Params

        gravityPoint?: number
      }
      export type ValueProps = string | number | boolean | plainObject | void | null
      export type OptionProps = {
        type?: 'button' | 'label'
        value: ValueProps
        label: ReactElement
        selectedLabel?: ReactElement
      }
    }
    export namespace List {
      export type ListTone = 'border' | 'cloud' | 'vivid' | 'normal' | 'plain'
      export type Methods = {
        Radio: ( props: PlainParams ) => JSX.Element
        Checkbox: ( props: PlainParams ) => JSX.Element
      }
      export type PlainParams = CoreParams & {
        tone?: ListTone
        icon?: boolean

        tabIndex?: number
        id?: string

        iconType?: 'radio' | 'checkbox'
        minSelect?: number


        disabled?: boolean
        value?: any | any[]
        options: OptionParams[]

        hideInput?: boolean

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false

        cellStyles?: TagProps.Params
        cellClassName?: string
        cellCheckedStyles?: TagProps.Params
        cellCheckedClassName?: string
        defaultActiveStyling?: boolean
      }
      export type OriginParams = PlainParams & {
        type: 'radio' | 'checkbox' | 'checker'
        tone: ListTone
      }
      export type OptionParams = {
        value: any
        label: ReactElement
        disabled?: boolean
        className?: string
        checkedStyles?: TagProps.Params
        checkedClassName?: string
      } & TagProps.Params
    }
    export namespace Chips {
      export type Methods = React.FC<PlainParams> & {
        fn: FNs
      }
      export type PlainParams = CoreParams & {
        tabIndex?: number

        id?: string

        disabled?: boolean

        value?: OptionParams[]
        limit?: number

        selectorGravityPoint?: number

        defaultOptions?: OptionParams[]
        onDynamicSearch?: onDynamicSearch

        leftIndicator?: ReactElement | false
        rightIndicator?: ReactElement | false
        rightIcon?: ReactElement | false
        leftIcon?: ReactElement | false

        SelectedCellComponent?: SelectedCellComponentInput
        SelectorCellComponent?: SelectorCellComponentInput
        AddButtonComponent?: AddButtonComponentInput
      }
      export type onDynamicSearch = {
        ( k: string ): Promise<{
          options: OptionParams[]
        }>
      }
      export type OptionParams = {
        value: any
        label: string
      }
      export type SelectedCellComponentInput = React.FC<{
        removeCallback: Function
        defaultRemoveButton: ReactElement
        openCallback(): void
        value: any
        label: string
      }>
      export type SelectorCellComponentInput = React.FC<{
        isSelected: boolean
        isFocused: boolean
        value: any
        label: string
      }>
      export type AddButtonComponentInput = React.FC<{
        selected: OptionParams[]
        openCallback(): void
      }>
      export type OpenSelectorInput = {
        parent: Jsmin.Args
        selectorID: string
        options: OptionParams[]
        selected: OptionParams[]
        bottomContent?: ReactElement
        gravityPoint?: number
        limit?: number
        onDynamicSearch?: {
          ( k: string ): Promise<{
            options: OptionParams[]
          }>
        }
        onUpdated( params: {
          values: any[]
        } ): void
        onClosed(): void
        SelectorCellComponent?: SelectorCellComponentInput
      }
      export type FNs = {
        openSelector( params: OpenSelectorInput ): void
        closeSelector( selectorID: string ): void
        updateOptions( selectorID: string,options: OptionParams[] ): void
        updateSelected( selectorID: string,selected: OptionParams[] ): void
      }
    }
    export namespace Search {
      export type PlainParams = Chips.PlainParams
    }
    export namespace Filer {
      export type Methods = React.FC<PlainParams> & FNs
      export type PlainParams = CoreParams & React.DOMAttributes<HTMLInputElement> & {
        tone?: BoxTone
        tabIndex?: number

        id?: string
        disabled?: boolean

        value?: CustomFile[]
        limit?: number

        fileNameEdit?: boolean
        systemOnly?: boolean
        accept?: Accept

        cellStyles?: TagProps.Params
        cellClassName?: string
      }
      export type CustomFile = File & {
        id: string
      }
      export type Accept = 'image' | string
      export type FNs = {
        fn: {
          openDialog( params: {
            accept?: Accept
            multiple?: boolean
          } ): Promise<File[]>
        }
      }
    }
    export namespace Slider {
      export type PlainParams = CoreParams & React.DOMAttributes<HTMLInputElement> & {
        tabIndex?: number

        id?: string

        disabled?: boolean

        value?: number

        color?: Color

        min: number
        max: number
        step: number
        legends?: {
          enable?: boolean
          custom?: LegendsCallback
          showAlways?: boolean
        }
      }
      export type Color = TagProps.ThemeColor | 'theme' | 'posi' | 'nega' | 'warn'
      export type LegendsCallback = {
        ( value: number ): ReactElement
      }
    }
    export namespace Switch {
      export type PlainParams = UniParams & React.DOMAttributes<HTMLInputElement> & {
        color?: Color

        id?: string
        tabIndex?: number

        appearance?: 'material' | 'applely'
        disabled?: boolean
        value?: boolean
        icon?: ReactElement
      }
      export type Color = TagProps.ThemeColor | 'theme' | 'posi' | 'nega' | 'warn'
    }
    export namespace Segmented {
      export type Tones = 'Border' | 'ThemeBorder' | 'BottomLine' | 'Cloud' | 'ThemeCloud' | 'WhiteCloud'
      export type Types = {
        Auto: ( params: Params ) => JSX.Element
        Normal: ( params: Params ) => JSX.Element

        Cloud: ( params: Params ) => JSX.Element
        Cloud2: ( params: Params ) => JSX.Element
        Cloud3: ( params: Params ) => JSX.Element

        Border: ( params: Params ) => JSX.Element
        Border2: ( params: Params ) => JSX.Element
        BottomLine: ( params: Params ) => JSX.Element
      }
      export type Params = List.PlainParams
      export type ListParams = List.OptionParams[]
    }
    export namespace Checker {
      export type PlainParams = CoreParams & {
        label: ReactElement

        id?: string
        tabIndex?: number

        disabled?: boolean
        value?: boolean


        cellStyles?: TagProps.Params
        cellClassName?: string
        cellCheckedStyles?: TagProps.Params
        cellCheckedClassName?: string
      }
    }
    export namespace Status {
      export type Plain = {
        componentID: string
        dataValue: any
        eventType: Validation.EventType
        eventID: string
      }
      export type Text = Plain & {
        formatValue: any
        prevValue: any
        caretFrom: number
        caretTo: number
      }
      export type DigitCharacters = Plain & {
        formatValue: any
      }
      export type Time = Plain & {
        formatValue: any
        ranges: Time.RangeProps[]
      }
      export type Slider = Plain & {
        min: number
        max: number
        step: number
      }
    }
    export namespace Validation {
      export type EventType = 'init' | 'update' | 'override' | 'refresh'
      export type Notice = {
        type: 'valid' | 'invalid' | 'warn'
        label: ReactElement
      }
      export type Result = {
        ok: boolean
        notice: Notice[]
      }
      export type SystemCheck = {
        ( props: {
          value: any
          params: any
        } ): Result
      }
      export type OnValidate = {
        ( state: {
          eventType: EventType,
          value: any,
          props: plainObject
        } ): Promise<Result>
      }
    }
    export type IndicatorParams = TagProps.Params & {
      tone?: BoxTone
      className?: string
      children: ReactElement
    }
  }
  export namespace Buttons {
    export type Methods = Seed & {}
    export type Seeds = 'Button' | 'Label' | 'Anchor'
    export type Tones = 'Plain' | 'Link' | 'Normal' | 'Border' | 'Prime' | 'Sub' | 'Clear' | 'FillToBorder' | 'BorderToFill'
    export type Sizes = 'XS' | 'S' | 'R' | 'L'
    export type Colors = 'theme' | 'posi' | 'nega' | 'warn' | 'cloud' | 'trans' | 'white' | 'plain'
    export type Seed = {
      Button: Tone<ButtonInput>
      Label: Tone<LabelInput>
      Anchor: Tone<AnchorInput>
    }
    export type Tone<T> = {
      Plain: React.FC<T>
      Link: React.FC<T>

      Normal: Size<T>
      Border: Size<T>

      Prime: Size<T & Tones.Prime>
      Sub: Size<T & Tones.Sub>
      Clear: Size<T & Tones.Clear>
      FillToBorder: Size<T & Tones.FillToBorder>
      BorderToFill: Size<T & Tones.BorderToFill>
    }
    export type Size<T> = {
      XS: React.FC<T>
      S: React.FC<T>
      R: React.FC<T>
      L: React.FC<T>
    }
    export namespace Tones {
      export type Plain = {}
      export type Link = {}
      export type Normal = {}
      export type Border = {}
      export type Prime = { color?: Colors | TagProps.ThemeColor }
      export type Sub = { color?: Colors | 'layer' }
      export type Clear = { color?: Colors | 'layer' }
      export type FillToBorder = { color?: Colors }
      export type BorderToFill = { color?: Colors }
    }
    export type UniParams = TagProps.BasicElement & {
      tabIndex?: number
      children?: ReactElement
      'aria-label'?: string
      isLocked?: boolean
      isActive?: boolean
      isActiveStyles?: TagProps.Params
      isActiveClassName?: string
    }
    export type delegateClickEventProps = 'auxEnter' | 'enter' | 'space'
    export type ButtonInput = UniParams & {
      submitOption?: {
        formName: string
        acceptInvalidForm?: boolean
        submitDelegationKey?: delegateClickEventProps | delegateClickEventProps[]
        callback( form: plainObject,ok: boolean ): void
      }
    } & React.ButtonHTMLAttributes<HTMLButtonElement>
    export type LabelInput = UniParams & {
      htmlFor?: string
    } & React.LabelHTMLAttributes<HTMLLabelElement>
    export type AnchorInput = UniParams & {
      href?: string
      newTab?: boolean
      sync?: boolean
      download?: any
      shiftQueryParams?: boolean
    } & React.ButtonHTMLAttributes<HTMLAnchorElement>
  }
  export namespace Sheet {
    export type Methods = {
      open( params: Params ): void

      refresh( params: Params,open: boolean ): void
      resize( params: {
        sheetID: string
        size: SizeParams
      } ): void
      reposition( sheetID: string ): void

      close( key: string,eventType?: 'Escape' | 'pageTransit',force?: boolean ): void
      closeGroup( keyGroup: string ): void
      closeAll( pageTransit?: boolean ): void
      Comps: {
        Body: React.FC<atoms.BoxInput>
      }
    }
    export type Params = NormalParams | EdgeParams | CustomParams | ImageParams | Bottom.Params
    export type UniParams = {
      sheetID?: string
      sheetGroups?: string | string[]
      backgroundEffect?: boolean
      content: ReactElement | {
        (): JSX.Element
      }
      overwrap?: boolean
      close_option?: CloseOptions
      hold_state?: boolean

      openAfter?(): void
      closeAfter?(): void
    } & TagProps.BasicElement
    export type SizeParams = 'S' | 'R' | 'L' | '2L' | '3L' | 'MAX'
    export type CloseOptions = {
      pageTransit?: boolean
      escapeKeyDown?: boolean
      aroundClick?: boolean
      elementBlur?: Jsmin.Args
    }
    export type Sheet =
      'normal.topLeft' |
      'normal.topCenter' |
      'normal.topRight' |
      'normal.middleLeft' |
      'normal.middleCenter' |
      'normal.middleRight' |
      'normal.bottomLeft' |
      'normal.bottomCenter' |
      'normal.bottomRight' |

      'drawer.left' | 'drawer.right' | 'drawer.bottom' |

      'custom' |
      'image'
    export type NormalParams = UniParams & {
      type: Sheet
      size?: SizeParams
    }
    export type EdgeParams = UniParams & {
      type: Sheet
      size?: SizeParams
    }
    export type CustomParams = UniParams & {
      type: 'custom'
      parent: Jsmin.Args
      gravityPoint?: number
    }
    export type ImageParams = Omit<UniParams,'content'> & {
      type: 'image'
      src: string | string[]
    }
    export namespace Bottom {
      export type Sizes = 'S' | 'R' | 'L'
      export type Params = UniParams & {
        type: 'drawer.bottom'
        size: Sizes
        sizeChanged?( size: Sizes ): void
        baseStyles?: TagProps.Params
        close_option?: CloseOptions & {
          swipeDown?: boolean
        }
      }
    }
  }
  export namespace Tooltips {
    export type Methods = {
      __memoryID: string
      open( params: Params ): void
      close( tipsID: string ): void
      closeALL(): void
      Comps: {
        Body: React.FC<atoms.BoxInput>
      }
    }
    export type Params = {
      tipsID?: string
      tipsGroups?: string | string[]
      parent: Jsmin.Args
      gravityPoint?: number
      close_option?: Sheet.CloseOptions
      hold_state?: boolean
      content: ReactElement | {
        (): JSX.Element
      }
      openAfter?(): void
      closeAfter?(): void
    } & TagProps.BasicElement
  }
  export namespace SnackBar {
    export type Methods = {
      __memoryID: string
      add( props: AddParams ): SnackBar.Methods
      remove( snackID: string ): SnackBar.Methods
      __launch(): void
    }
    export type AddParams = Omit<atoms.BoxInput,'children'> & {
      children?: ReactElement | {
        (): JSX.Element
      }
      customChildren?: {
        ( params: {
          close(): void
        } ): JSX.Element
      }
      snackID?: string
      secondsToClose?: number
    }
  }
  export namespace Loader {
    export type Methods = Color & FNs
    export type Color = {
      Theme: Size<CompInput>
      Posi: Size<CompInput>
      Nega: Size<CompInput>
      Warn: Size<CompInput>
      White: Size<CompInput>
      Cloud: Size<CompInput>
    }
    export type Size<T> = {
      S: React.FC<T>
      R: React.FC<T>
      L: React.FC<T>
      XL: React.FC<T>
      MAX: React.FC<T>
    }
    export type Sizes = 'S' | 'R' | 'L' | 'XL' | 'MAX'
    export type Colors = 'theme' | 'posi' | 'nega' | 'warn' | 'white' | 'cloud'
    export type CompInput = TagProps.Params & {
      showInitial?: boolean
      loaderID?: string
    }
    export type FNs = {
      __memoryID: string
      __launch(): void
      fn: {
        stopALL(): void
        top: {
          active(): void
          stop(): void
        }
        corner: {
          active(): void
          stop(): void
        }
        mini: {
          active( loaderID?: string ): void
          stop( loaderID?: string ): void
          stopALL(): void
        }
      }
    }
  }
  export namespace Cropper {
    export type Use = 'square' | 'wallpaper.horizontal' | 'wallpaper.vertical'
    export type Params = {
      use: Use
      develops: DevelopParams[]
      onProcessFinished: {
        ( files: Input.Filer.CustomFile[] ): void
      }
    }
    export type DevelopParams = {
      size: 'S' | 'R' | 'L'
      maxSize?: number
    }
    export type Methods = {
      open( params: Params ): void
    }
  }
  export namespace Effects {
    export type FadeUniParams = atoms.BoxInput & {
      animationTime?: number
      animationDelay?: number
    }
    export type Methods = {
      FadeIn: React.FC<FadeUniParams>
      FadeUp: React.FC<FadeUniParams>
      // NumberCount: React.FC<{
      //   from: number
      //   to: number
      //   ms:number
      //   cb?: {
      //     ( value: number ): ReactElement
      //   }
      // }>
    }
  }
  export type Methods = {
    Table: fn.Tables.Methods
    Layout: fn.Layout.Methods
    Buttons: fn.Buttons.Methods
    Input: fn.Input.Methods
    Sheet: fn.Sheet.Methods
    SnackBar: fn.SnackBar.Methods
    Loader: fn.Loader.Methods
    Tooltips: fn.Tooltips.Methods
    Effects: fn.Effects.Methods
    Cropper: fn.Cropper.Methods
  }
}