import { ParserOptions, ParseError } from '@babel/parser';
import { IMangleOptions, IMangleScopeContext } from '@weapp-tailwindcss/mangle';
export { IMangleScopeContext } from '@weapp-tailwindcss/mangle';
import { CssPreflightOptions, LoadedPostcssOptions, CustomRuleCallback, IStyleHandlerOptions } from '@weapp-tailwindcss/postcss';
export { CssPreflightOptions, IStyleHandlerOptions } from '@weapp-tailwindcss/postcss';
import { SourceMap } from 'magic-string';
import { Result, Root, Document } from 'postcss';
import { PatchOptions, ILengthUnitsPatchOptions, TailwindcssPatcherOptions, TailwindcssPatcher } from 'tailwindcss-patch';
import { Buffer } from 'node:buffer';
import { sources } from 'webpack';
import { LRUCache } from 'lru-cache';
import { pluginOptions } from 'postcss-preset-env';

interface HashMapValue {
    hash: string;
    changed: boolean;
}
type HashMapKey = string | number;
type CacheValue = sources.Source | string;
interface ICreateCacheReturnType {
    hashMap: Map<HashMapKey, HashMapValue>;
    instance: LRUCache<string, CacheValue>;
    hasHashKey: (key: HashMapKey) => boolean;
    getHashValue: (key: HashMapKey) => HashMapValue | undefined;
    setHashValue: (key: HashMapKey, value: HashMapValue) => this['hashMap'];
    computeHash: (message: string | Buffer) => string;
    get: <V extends CacheValue = sources.Source>(key: string) => V | undefined;
    set: <V extends CacheValue = sources.Source>(key: string, value: V) => this['instance'];
    has: (key: string) => boolean;
    calcHashValueChanged: (key: HashMapKey, hash: string) => this;
    process: (key: string, callback: () => void | false | Promise<void | false>, fallback: () => void | {
        key: string;
        source: CacheValue;
    } | Promise<void | {
        key: string;
        source: CacheValue;
    }>) => void | Promise<void>;
}

interface UserDefinedOptions {
    /**
     * @group 0.重要配置
     * @description 是否禁用此插件，一般用于构建到多平台时使用，比如小程序时不传，非小程序环境(h5,app)传入一个 `true`
     * ```ts
     * // 比如 uni-app vue3 vite
     * import process from 'node:process'
     
  const isH5 = process.env.UNI_PLATFORM === 'h5'
  const isApp = process.env.UNI_PLATFORM === 'app'
  const WeappTailwindcssDisabled = isH5 || isApp
     
  import { UnifiedViteWeappTailwindcssPlugin as uvtw } from 'weapp-tailwindcss/vite'
  // 注册插件
  // highlight-start
      uvtw({
        disabled: WeappTailwindcssDisabled,
      }),
  // highlight-end
     * ```
     */
    disabled?: boolean;
    /**
     * @group 0.重要配置
     * @description **这是一个重要的配置!**
     
  它可以自定义`wxml`标签上的`attr`转化属性。默认转化所有的`class`和`hover-class`，这个`Map`的 `key`为匹配标签，`value`为属性字符串或者匹配正则数组。
     
  如果你想要增加，对于所有标签都生效的转化的属性，你可以添加 `*`: `(string | Regexp)[]` 这样的键值对。(`*` 是一个特殊值，代表所有标签)
     
  更复杂的情况，可以传一个 `Map<string | Regex, (string | Regex)[]>`实例。
     
  假如你要把 `className` 通过组件的`prop`传递给子组件，又或者想要自定义转化的标签属性时，需要用到此配置，案例详见：[issue#129](https://github.com/sonofmagic/weapp-tailwindcss/issues/129#issuecomment-1340914688),[issue#134](https://github.com/sonofmagic/weapp-tailwindcss/issues/134#issuecomment-1351288238)
     
  @example
     
  ```js
  const customAttributes = {
      // 匹配所有带 Class / class 相关的标签，比如某个组件上的 `a-class`, `testClass` , `custom-class` 里面的值
      '*': [ /[A-Za-z]?[A-Za-z-]*[Cc]lass/ ],
      // 额外匹配转化 `van-image` 标签上属性为 `custom-class` 的值
      'van-image': ['custom-class'],
      // 转化所有 `ice-button` 标签上属性为 `testClass` 的值
      'ice-button': ['testClass']
  }
  ```
     
  当然你可以根据自己的需求，定义单个或者多个正则/字符串。
     
  甚至有可能你编写正则表达式，它们匹配的范围，直接包括了插件里自带默认的 `class`/`hover-class`，那么这种情况下，你完全可以取代插件的默认模板转化器，开启 [disabledDefaultTemplateHandler](/docs/api/interfaces/UserDefinedOptions#disableddefaulttemplatehandler) 配置项,禁用默认的模版匹配转化器。
     */
    customAttributes?: ICustomAttributes;
    /**
     * @group 0.重要配置
     * @description 自定义转化class名称字典，这个配置项用来自定义转化`class`名称字典,你可以使用这个选项来简化生成的`class`
  - 默认模式: 把小程序中不允许的字符串，转义为**相等长度**的代替字符串，这种情况不追求转化目标字符串的一比一绝对等价，即无法从生成结果，反推原先的`class`
     
  当然，你也可以自定义，传一个 `Record<string, string>` 类型，只需保证转化后 css 中的 `class` 选择器，不会和自己定义的 `class` 产生冲突即可，示例见[dic.ts](https://github.com/sonofmagic/weapp-core/blob/main/packages/escape/src/dic.ts)
     * @default MappingChars2String
     */
    customReplaceDictionary?: Record<string, string>;
    /**
     * @version `^4.0.0`
     * @group 0.重要配置
     * @description js 忽略标签模板表达式中的标识符，这样使用标识符包裹的模板字符串不会被转义
     * @default ['weappTwIgnore']
     */
    ignoreTaggedTemplateExpressionIdentifiers?: (string | RegExp)[];
    /**
     * @version `^4.0.0`
     * @group 0.重要配置
     * @description js 忽略调用表达式中的标识符，这样使用这个方法，包裹的模板字符串和字符串字面量不会被转义，一般用来配合 `@weapp-tailwindcss/merge` 使用，比如设置为 `['twMerge', 'twJoin', 'cva']`
     */
    ignoreCallExpressionIdentifiers?: (string | RegExp)[];
    /**
     * @group 0.重要配置
     * @issue https://github.com/sonofmagic/weapp-tailwindcss/issues/7
     * @description 在所有 view节点添加的 css 预设，可根据情况自由的禁用原先的规则，或者添加新的规则。默认预置 `css` 同 `tailwindcss` 类似，详细用法如下:
     * ```js
     * // default 默认，这代表会添加给所有的 view / text 元素, 受到 cssPreflightRange 配置项影响 :
      cssPreflight: {
        'box-sizing': 'border-box',
        'border-width': '0',
        'border-style': 'solid',
        'border-color': 'currentColor'
      }
      // result
      // box-sizing: border-box;
      // border-width: 0;
      // border-style: solid;
      // border-color: currentColor
     
      // case 禁用所有
      cssPreflight: false
      // result
      // none
     
      // case 禁用单个属性
      cssPreflight: {
        'box-sizing': false
      }
      // border-width: 0;
      // border-style: solid;
      // border-color: currentColor
     
      // case 更改和添加单个属性
      cssPreflight: {
        'box-sizing': 'content-box',
        'background': 'black'
      }
      // result
      // box-sizing: content-box;
      // border-width: 0;
      // border-style: solid;
      // border-color: currentColor;
      // background: black
     * ```
     */
    cssPreflight?: CssPreflightOptions;
    /**
     * @group 0.重要配置
     * @issue https://github.com/sonofmagic/weapp-tailwindcss/pull/62
     * @description 全局`dom`选择器，只有在这个选择器作用范围内的`dom`会被注入 `cssPreflight` 的变量和默认样式。只对所有的 `view`,`text` 和伪元素生效，想要对所有的元素生效，可切换为 `'all'`,此时需要自行处理和客户端默认样式的冲突
     */
    cssPreflightRange?: 'all';
    /**
     * @group 0.重要配置
     * @version `^2.6.0`
     * @description  是否注入额外的 `tailwindcss css var scope` 区域，这个选项用于这样的场景
     *
     * 比如 `taro vue3` 使用 [NutUI](https://nutui.jd.com), 需要使用 `@tarojs/plugin-html`，而这个插件会启用 `postcss-html-transform` 从而移除所有带 `*` 选择器
     *
     * 这会导致 `tailwindcss css var scope` 区域被移除导致一些样式，比如渐变等等功能失效
     *
     * 这种场景下，启用这个选项会再次重新注入整个 `tailwindcss css var scope`
     *
     * @default false
     */
    injectAdditionalCssVarScope?: boolean;
    /**
     * @group 0.重要配置
     * @description 用于处理 css 选择器的替换规则
     */
    cssSelectorReplacement?: {
        /**
         * @default `'page'` <br/>
         * @description 把`css`中的全局选择器 **`:root`** 替换为指定值，默认替换为 `'page'`，设置为 `false` 时不进行替换
         */
        root?: string | string[] | false;
        /**
         * @issue https://github.com/sonofmagic/weapp-tailwindcss/issues/81 <br/>
         * @default `['view','text']` <br/>
         * @description 把`css`中的全局选择器 **`*`** 替换为指定值，默认替换为 `'view','text'`，设置为 `false` 时不进行替换，此时小程序会由于不认识`*`选择器而报错
         */
        universal?: string | string[] | false;
    };
    /**
     * @version `^3.0.0`
     * @group 0.重要配置
     * @description rem 转 rpx 配置，默认为 `undefined` 不开启，可传入 `true` 启用默认配置项，也可传入自定义配置项，配置项列表见 [postcss-rem-to-responsive-pixel](https://www.npmjs.com/package/postcss-rem-to-responsive-pixel)
     * ```ts
     * // 默认值
     * {
     *  rootValue: 32,
     *  propList: ['*'],
     *  transformUnit: 'rpx',
     * }
     * ```
     */
    rem2rpx?: boolean | UserDefinedOptions;
    /**
     * @version `^4.0.0`
     * @group 0.重要配置
     * @description postcss-preset-env 的入参数
     */
    cssPresetEnv?: pluginOptions;
    /**
     * @version `^4.0.0`
     * @group 0.重要配置
     * @description 配置不同版本 tailwindcss 的行为
     */
    tailwindcss?: PatchOptions['tailwindcss'];
}
interface UserDefinedOptions {
    /**
     * @group 1.文件匹配
     * @description 匹配 `wxml`等等模板进行处理的方法
     */
    htmlMatcher?: (name: string) => boolean;
    /**
     * @group 1.文件匹配
     * @description 匹配 `wxss` 等等样式文件的方法
     */
    cssMatcher?: (name: string) => boolean;
    /**
     * @group 1.文件匹配
     * @description 匹配编译后 `js` 文件进行处理的方法
     */
    jsMatcher?: (name: string) => boolean;
    /**
     * @group 1.文件匹配
     * @description `tailwindcss css var inject scope` 的匹配方法,用于处理原始变量和替换不兼容选择器。可以不传，但是遇到某些 `::before/::after` 选择器注入冲突时，建议传入参数手动指定 css bundle 文件位置
     *
     */
    mainCssChunkMatcher?: (name: string, appType?: AppType) => boolean;
    /**
     * @group 1.文件匹配
     * @experiment 实验性质，有可能会改变
     * @description 各个平台 `wxs` 文件的匹配方法,可以设置为包括微信的 .wxs,支付宝的 .sjs 和 百度小程序的 .filter.js
     * > tip: 记得在 `tailwind.config.js` 中，把 `wxs` 这个格式加入 `content` 配置项，不然不会生效
     * @default ()=>false
     */
    wxsMatcher?: (name: string) => boolean;
    /**
     * @group 1.文件匹配
     * @experiment 实验性质，有可能会改变
     * @description 是否转义 `wxml` 中内联的 `wxs`
     * > tip: 记得在 `tailwind.config.js` 中，把 `wxs` 这个格式加入 `content` 配置项，不然不会生效
     * @example
     * ```html
     * <!-- index.wxml -->
     * <wxs module="inline">
  // 我是内联wxs
  // 下方的类名会被转义
    var className = "after:content-['我是className']"
    module.exports = {
      className: className
    }
  </wxs>
  <wxs src="./index.wxs" module="outside"/>
  <view><view class="{{inline.className}}"></view><view class="{{outside.className}}"></view></view>
     * ```
     * @default false
     */
    inlineWxs?: boolean;
}
interface UserDefinedOptions {
    /**
     * @group 2.生命周期
     * @description plugin apply 初调用
     */
    onLoad?: () => void;
    /**
     * @group 2.生命周期
     * @description 开始处理时调用
     */
    onStart?: () => void;
    /**
     * @description 匹配成功并修改文件内容前调用
     */
    /**
     * @group 2.生命周期
     * @description 匹配成功并修改文件内容后调用
     */
    onUpdate?: (filename: string, oldVal: string, newVal: string) => void;
    /**
     * @group 2.生命周期
     * @description 结束处理时调用
     */
    onEnd?: () => void;
}
interface UserDefinedOptions {
    /**
     * @group 3.一般配置
     * @issue https://github.com/sonofmagic/weapp-tailwindcss/issues/110
     * @description 自从`tailwindcss 3.2.0`对任意值添加了长度单位的校验后，小程序中的`rpx`这个`wxss`单位，由于不在长度合法名单中，于是被识别成了颜色，导致与预期不符，详见：[issues/110](https://github.com/sonofmagic/weapp-tailwindcss/issues/110)。所以这个选项是用来给`tailwindcss`运行时，自动打上一个支持`rpx`单位的补丁。默认开启，在绝大部分情况下，你都可以忽略这个配置项，除非你需要更高级的自定义。
  > 目前自动检索可能存在一定的缺陷，它会在第一次运行的时候不生效，关闭后第二次运行才生效。这是因为 nodejs 运行时先加载好了 `tailwindcss` 模块 ，然后再来运行这个插件，自动给 `tailwindcss` 运行时打上 `patch`。此时由于 `tailwindcss` 模块已经加载，所以 `patch` 在第一次运行时不生效，`ctrl+c` 关闭之后，再次运行才生效。这种情况可以使用:
     
  ```diff
   "scripts": {
  +  "postinstall": "weapp-tw patch"
   }
  ```
     
  使用 `npm hooks` 的方式来给 `tailwindcss` 自动打 `patch`
     */
    supportCustomLengthUnitsPatch?: ILengthUnitsPatchOptions | boolean;
    /**
     * @group 3.一般配置
     * @description 使用的框架类型(uni-app,taro...)，用于找到主要的 `css bundle` 进行转化，这个配置会影响默认方法 `mainCssChunkMatcher` 的行为，不传会去猜测 `tailwindcss css var inject scope` (tailwindcss 变量注入的位置) 的位置
     */
    appType?: AppType;
    /**
     * @group 3.一般配置
     * @description 针对 tailwindcss arbitrary values 的一些配置
     */
    arbitraryValues?: IArbitraryValues;
    /**
     * @group 3.一般配置
     * @version `^2.6.1`
     * @description 当 `tailwindcss` 和 `js` 处理的字面量撞车的时候，配置此选项可以用来保留js字面量，不进行转义处理。返回值中，想要当前js字面量保留，则返回 `true`。想要转义则返回 `false/undefined`
     * @default 保留所有带 `*` js字符串字面量
     */
    jsPreserveClass?: (keyword: string) => boolean | undefined;
    /**
     * @group 3.一般配置
     * @version `^2.6.2`
     * @description 开启此选项，将会禁用默认 `wxml` 模板替换器，此时模板的匹配和转化将完全被 [`customAttributes`](/docs/api/interfaces/UserDefinedOptions#customattributes) 接管，
     *
     * 此时你需要自己编写匹配之前默认 `class`/`hover-class`，以及新的标签属性的正则表达式`regex`
     * @default false
     */
    disabledDefaultTemplateHandler?: boolean;
    /**
     * @ignore
     * @internal
     */
    runtimeLoaderPath?: string;
    /**
     * @group 3.一般配置
     * @version `^2.9.3`
     * @description 用于指定路径来获取 tailwindcss 上下文，一般情况下不用传入，使用 linked / monorepo 可能需要指定具体位置，路径通常是目标项目的 package.json 所在目录
     */
    tailwindcssBasedir?: string;
    /**
     * @group 3.一般配置
     * @version `^3.0.11`
     * @description 缓存策略
     */
    cache?: boolean | ICreateCacheReturnType;
    /**
     * @version `^3.2.0`
     * @group 3.一般配置
     * @description 对解析 js 使用的 `@babel/parser` 工具的配置
     */
    babelParserOptions?: ParserOptions & {
        cache?: boolean;
    };
    /**
     * @group 3.一般配置
     * @description 用于控制 tailwindcss 子组合器的生效标签范围, 这里我们用一个例子来说明这个配置是干啥用的.
     *
     * 我们布局的时候往往会使用 `space-x-4`
     * 那么实际上会生成这样的css选择器:
     * ```css
     * .space-x-4>:not([hidden])~:not([hidden]){}
     * ```
     * 然而很不幸，这个选择器在小程序中是不支持的，写了会报错导致编译失败。
     * 所以出于保守起见，我把它替换为了：
     * ```css
     * .space-x-4>view + view{}
     * ```
     * 这同时也是默认值, 而这个选项就允许你进行自定义子组合器的行为
     *
     * 你可以传入一个 字符串，或者字符串数组
     * 1. 传入字符串数组,比如 `['view','text']` 生成:
     * ```css
     * .space-y-4>view + view,text + text{}
     * ```
     *
     * 2. 传入一个字符串，此时行为变成了整个替换，比如 `'view,text,button,input ~ view,text,button,input'` 生成:
     * ```css
     * .space-y-4>view,text,button,input ~ view,text,button,input{}
     * ```
     * @default 'view + view'
     */
    cssChildCombinatorReplaceValue?: string | string[];
    /**
     * @version `^3.2.0`
     * @group 3.一般配置
     * @description 对解析 css 使用的 `postcss` 工具的配置
     */
    postcssOptions?: LoadedPostcssOptions;
    /**
     * @version `^3.2.1`
     * @group 3.一般配置
     * @issue https://github.com/sonofmagic/weapp-tailwindcss/issues/293
     * @default `true`
     * @description 是否删除 css :hover 选择器节点，默认为 `true`, 原因在于，小程序 css :hover 是不生效的，要使用 view 这种标签的 hover-class 属性
     */
    cssRemoveHoverPseudoClass?: boolean;
    /**
     * @version `^4.1.2`
     * @group 3.一般配置
     * @default `true`
     * @description 是否删除 `@property` 选择器节点，默认为 `true`, 原因在于，小程序 `@property` 是不生效的
     */
    cssRemoveProperty?: boolean;
    /**
     * @group 3.一般配置
     * @description 用于自定义处理 css 的回调函数，可根据 Postcss walk 方法自由定制处理方案的 callback 方法
     */
    customRuleCallback?: CustomRuleCallback;
    /**
     * @group 3.一般配置
     * @description 自定义 patcher 参数
     */
    tailwindcssPatcherOptions?: TailwindcssPatcherOptions;
}
interface UserDefinedOptions {
    /**
     * @group 4.即将废弃配置
     * @description 对解析 js 使用的 ast 工具，默认情况使用 `babel`，可以通过安装 `@ast-grep/napi`，同时启用 `ast-grep` 配置项，来启用 `ast-grep` 来处理 `js`，速度会是 `babel` 的 `2` 倍左右
     * :::danger
     * 此配置即将在 `5.x` 被弃用
     *
     * 废弃原因:
     *
     * 虽然 `@ast-grep/napi` 提供了更快的速度，但是 `babel` 有更强的静态分析 `js` 能力，使得后续一些新功能的开发无法使用 `@ast-grep/napi` 实现，所以废弃只保留 `babel` 的方式
     * :::
     */
    jsAstTool?: 'babel' | 'ast-grep';
    /**
     * @group 4.即将废弃配置
     * @description 是否压缩混淆 `wxml`,`js` 和 `wxss` 中指定范围的 `class` 以避免选择器过长问题，默认为`false`不开启，详细配置见 [unplugin-tailwindcss-mangle](https://github.com/sonofmagic/tailwindcss-mangle/tree/main/packages/unplugin-tailwindcss-mangle)
     * :::danger
     * 此配置即将在 `5.x` 被弃用
     *
     * 废弃原因:
     *
     * mangle 相关的功能会被迁移到另外一个项目： [`tailwindcss-mangle`](https://github.com/sonofmagic/tailwindcss-mangle) 中去，还想要这个功能可以2个插件结合使用
     * :::
     */
    mangle?: boolean | IMangleOptions;
}

type ItemOrItemArray<T> = T | T[];

type AppType = 'uni-app' | 'uni-app-vite' | 'taro' | 'remax' | 'rax' | 'native' | 'kbone' | 'mpx' | 'weapp-vite';
interface InternalCssSelectorReplacerOptions {
    mangleContext?: IMangleScopeContext;
    escapeMap?: Record<string, string>;
}
interface JsHandlerResult {
    code: string;
    map?: SourceMap;
    error?: ParseError;
}
type ICustomAttributes = Record<string, ItemOrItemArray<string | RegExp>> | Map<string | RegExp, ItemOrItemArray<string | RegExp>>;
type ICustomAttributesEntities = [string | RegExp, ItemOrItemArray<string | RegExp>][];
interface IJsHandlerOptions {
    escapeMap?: Record<string, string>;
    classNameSet?: Set<string>;
    arbitraryValues?: IArbitraryValues;
    mangleContext?: IMangleScopeContext;
    jsPreserveClass?: (keyword: string) => boolean | undefined;
    needEscaped?: boolean;
    generateMap?: boolean;
    alwaysEscape?: boolean;
    unescapeUnicode?: boolean;
    babelParserOptions?: ParserOptions;
    ignoreTaggedTemplateExpressionIdentifiers?: (string | RegExp)[];
    ignoreCallExpressionIdentifiers?: (string | RegExp)[];
}
interface IArbitraryValues {
    /**
     * 是否允许在类名里，使用双引号。
     * 建议不要开启，因为有些框架，比如 `vue3` 它针对有些静态模板会直接编译成 `html` 字符串，此时开启这个配置很有可能导致转义出错
     *
     * @example
     * ```html
     * <!-- 开启前默认只允许单引号 -->
     * <view class="after:content-['对酒当歌，人生几何']"></view>
     * <!-- 开启后 -->
     * <view class="after:content-[\"对酒当歌，人生几何\"]"></view>
     * ```
     *
     * @default `false`
     */
    allowDoubleQuotes?: boolean;
}
interface JsHandler {
    (rawSource: string, set: Set<string>, options?: CreateJsHandlerOptions): JsHandlerResult;
}
interface ICommonReplaceOptions {
    keepEOL?: boolean;
    escapeMap?: Record<string, string>;
}
interface ITemplateHandlerOptions extends ICommonReplaceOptions {
    customAttributesEntities?: ICustomAttributesEntities;
    escapeMap?: Record<string, string>;
    mangleContext?: IMangleScopeContext;
    inlineWxs?: boolean;
    jsHandler?: JsHandler;
    runtimeSet?: Set<string>;
    disabledDefaultTemplateHandler?: boolean;
    quote?: string | null;
    ignoreHead?: boolean;
}
type InternalUserDefinedOptions = Required<Omit<UserDefinedOptions, 'supportCustomLengthUnitsPatch' | 'customReplaceDictionary' | 'cache'> & {
    supportCustomLengthUnitsPatch: ILengthUnitsPatchOptions | boolean;
    templateHandler: (rawSource: string, options?: ITemplateHandlerOptions) => Promise<string>;
    styleHandler: (rawSource: string, options?: IStyleHandlerOptions) => Promise<Result<Root | Document>>;
    jsHandler: JsHandler;
    escapeMap: Record<string, string>;
    customReplaceDictionary: Record<string, string>;
    setMangleRuntimeSet: (runtimeSet: Set<string>) => void;
    cache: ICreateCacheReturnType;
    twPatcher: TailwindcssPatcher;
}>;
type InternalPostcssOptions = Pick<UserDefinedOptions, 'cssMatcher' | 'mainCssChunkMatcher' | 'cssPreflight' | 'cssPreflightRange' | 'customRuleCallback' | 'disabled'>;
interface IBaseWebpackPlugin {
    options: InternalUserDefinedOptions;
    appType?: AppType;
    apply: (compiler: any) => void;
}
/**
 * @description InternalPatchResult
 */
interface InternalPatchResult {
    dataTypes?: string;
    processTailwindFeatures?: string;
    plugin?: string;
}
type CreateJsHandlerOptions = Omit<IJsHandlerOptions, 'classNameSet'>;

export type { AppType, CreateJsHandlerOptions, IArbitraryValues, IBaseWebpackPlugin, ICommonReplaceOptions, ICustomAttributes, ICustomAttributesEntities, IJsHandlerOptions, ITemplateHandlerOptions, InternalCssSelectorReplacerOptions, InternalPatchResult, InternalPostcssOptions, InternalUserDefinedOptions, ItemOrItemArray, JsHandler, JsHandlerResult, UserDefinedOptions };
