![图片[1]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://www.mohe-sc.com/wp-content/uploads/2026/08/3ds-Max商业脚本开发者必备!插件、脚本、资产保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与恶意代码拦截一套搞定!-1024x576.jpg)
前段时间,小编在写《3ds Max迎来AI升级!MoHeTools For 3ds Max 2012 ~ 2026 智能工具箱插件发布,支持AI 3D建模、文生图、图生图、效果图生成,全面提升室内设计效率 [ 免费内测 ] !》期间和本站会员@김지연聊起了脚本加密相关问题,김지연觉得把混淆和加密放在MoHeTools For 3ds Max 2012 ~ 2026 智能工具箱里面使用不方便,希望可以有个独立的加密、混淆,模型保护功能的工具,使用方便,不用打开进3ds Max就能完成操作,김지연第二天就有脚本需要定制加密工具的需求,小编觉得김지연思路挺好,于是一拍即可就定制写了这个工具,插件大部分的加密、混淆、验证逻辑和想法来自于和김지연沟通过程的需求,在此感谢会员김지연提供的定制费用和思路想法!
做过 3ds Max 插件或者 MaxScript 脚本开发的人,基本都会碰到一个很现实的问题:自己花几天甚至几个月写出来的脚本,最终交付给客户的却是 .ms 源文件。别人用记事本、VS Code 打开就能直接看到核心代码,界面逻辑、算法、接口地址甚至授权判断都可能被复制。如果是准备商业销售的 3ds Max 插件,仅仅把代码打包一下显然不够。
今天介绍的MoHe Script v1.0,并不是单纯给 MaxScript 做混淆加密的小工具。它已经把3ds Max脚本调用、3ds Max脚本桥接运行、 MaxScript代码混淆、AES-256加密、3ds Max原生MSE编译、运行密钥、试用期限制、HWID授权、恶意脚本扫描、脚本库以及3ds Max联动执行 等功能整合到一个桌面工具中。
MoHe Script v1.0 当前版本标记为 v2026.8.02 Enterprise Protection,并明确将 3ds Max脚本调用、3ds Max脚本桥接运行、 MaxScript代码混淆、AES-256加密、3ds Max原生MSE编译、资产加密、模型加密,运行密钥、试用期限制、HWID授权、恶意脚本扫描、脚本库以及3ds Max联动执行 列为核心能力。
如果你平时需要开发和分发 .ms、.mcr、.mse 或 Python 类型的 3ds Max 工具,这套程序解决的其实不只是“代码看不懂”这么简单,而是把代码保护、商业授权、脚本安全检查和日常脚本管理放到了同一个工作流里。
MoHe Script v1.0 是什么?
MoHe Script v1.0 是一款面向 3ds Max / MaxScript 开发者设计的独立桌面工具,同时也有3ds Max脚本库,和资产模型加密,给被老赖伤害过的设计有个兜底功能,不输入密码,模型打不开!但真正值得关注的是它背后的几套独立引擎。例如程序内部包含 MaxScriptObfuscator、MaxScriptCompiler、SecurityEngine、MaxScriptTrialEngine…….等模块。换句话说,它并不是简单把一段 MaxScript 文本进行替换,而是针对脚本开发、脚本保护、脚本授权、脚本运行和管理设计了一套相对完整的处理链。
实际可以把整个工作流程理解为:MaxScript源代码 → 安全扫描 → 代码混淆/加密 → 授权保护 → MSE编译 → 分发给用户 → 3ds Max运行,对于商业脚本作者来说,这种方式比单独寻找一个“MaxScript混淆器”更加实用,因为代码保护只是第一步,后面还有授权、试用、交付和维护。
MoHe Script v1.0 好用更要好看
![图片[2]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/21/3ds-MaxMaxScriptMSE1.jpg)
在当今“颜值即生产力”的时代,优秀的软件产品不仅需要强大的功能体系,更需要具备令人愉悦的视觉体验。一个真正成熟的程序,不应该只是冰冷的功能集合,而应该从最初的产品设计阶段,就建立完整的 UI 视觉管理体系,让功能逻辑与美学设计深度融合。无论是开发工具、设计软件还是AI应用,界面体验已经成为用户选择和长期使用的重要因素。
从程序诞生之初,UI设计就融入整体架构之中,不再是后期简单添加的外观包装。系统采用现代化视觉设计理念,支持半透明毛玻璃(Glassmorphism)效果、多色主题切换、渐变动态头像、动态视觉元素以及统一的组件管理,让用户可以根据个人偏好打造专属界面风格。同时,通过合理的信息层级和空间布局,让复杂功能保持清晰易用,在专业效率与视觉美感之间取得平衡。
除了视觉风格的自由调整,程序还提供灵活的窗口管理能力,支持界面自由缩放、模块化布局以及不同使用场景下的自适应调整。用户可以根据工作习惯调整工具面板、功能区域和显示比例,让软件不仅“看起来舒服”,更能够真正提升工作效率。未来的软件竞争,不仅是功能强弱的竞争,也是设计理念、交互体验和用户情感连接的竞争。
智能化视觉主题管理系统:透明度调节与多主题切换
为了满足不同用户的视觉偏好,程序内置了完善的界面主题管理功能,支持窗口透明度自由调整以及多套配色方案快速切换。用户无需修改配置文件,即可通过可视化操作打造符合个人习惯的专属工作环境。
毛玻璃窗口透明度调节
系统提供独立的透明度控制滑块,支持从 50% 到 100% 的自由调整。通过调整窗口透明效果,可以实现类似现代化桌面应用的毛玻璃视觉风格,让界面更加轻盈,同时保持内容清晰可读,用户可以根据不同使用场景选择合适透明度:
| 较低透明度: | 增强背景融合效果,打造沉浸式视觉体验; |
| 中等透明度: | 兼顾美观与信息可读性,适合日常工作; |
| 高透明度: | 保持传统清晰界面,提高操作效率。 |
多色主题方案:打造个性化界面风格
![图片[3]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/21/3ds-MaxMaxScriptMSE0.jpg)
系统内置多套精心设计的主题配色方案,用户可以根据使用习惯、工作环境以及个人审美快速切换不同视觉风格。所有主题均支持即时生效,无需重启程序,让界面始终保持舒适、美观的操作体验。
| 主题名称 | 视觉风格 | 适用场景 |
|---|---|---|
| 曜石黑(默认) | 深色科技风,低调沉稳,减少长时间使用的视觉疲劳 | 日常开发、专业工具、高频操作 |
| 象牙白 | 明亮简洁,整体更加清爽,提高界面可读性 | 办公环境、浅色视觉偏好用户 |
| 深空蓝 | 未来科技感配色,突出专业与智能化氛围 | AI工具、设计软件、技术开发 |
| 钛金银 | 高级金属质感,简约大气,增强软件品质感 | 商业展示、专业工作场景 |
| 嫩草绿 | 清新自然,降低视觉压力,让界面更加轻松 | 长时间使用、个性化设置 |
| 樱花粉 | 柔和明亮,增加界面的年轻化与个性化体验 | 女性用户、创意设计场景 |
通过多主题系统,程序不仅提供功能层面的扩展能力,同时让用户拥有更自由的视觉管理方式。无论是追求专业科技感,还是喜欢轻松个性化风格,都可以快速切换属于自己的专属界面。
完整定制的3ds Max 联动与脚本执行交互中心
为了提升脚本工具与 3ds Max 之间的协同效率,系统提供了专用的联动交互管理模块,负责处理脚本执行、窗口通信、自动化操作以及异常反馈,让 MaxScript 与 3ds Max 之间实现更加稳定、高效的连接。
通过该模块,用户可以自由配置脚本运行行为,无需频繁手动切换窗口或执行重复操作,大幅提升脚本开发与插件使用效率。
| 功能 | 说明 |
|---|---|
| 自动注入 3ds Max 实时桥接脚本 | 启动后自动向 3ds Max 注入通信脚本,建立程序与 Max 环境之间的数据交互通道 |
| 开启视口原生 OLE 文件拖放 | 支持将文件直接拖入 3ds Max 视口,实现快速素材导入与操作 |
| 执行脚本自动激活 3ds Max 视口 | 运行脚本时自动切换并激活 Max 窗口,避免脚本执行无响应 |
| 自动将命令转发至 Windows 剪贴板 | 支持脚本命令快速传递,提高脚本执行效率 |
| 自动捕获 MaxScript 错误并弹窗提醒 | 实时检测脚本运行异常,并通过提示窗口反馈错误信息,方便快速定位问题 |
实时桥接通道管理
系统会自动创建实时桥接通信通道:实时桥接通道已建立(%TEMP%/_magicbox_cmd.ms)该通道用于连接外部程序与 3ds Max 内部 MaxScript 环境,实现:
- 外部程序发送脚本指令;
- MaxScript 接收并执行命令;
- 实时返回执行状态;
- 自动处理脚本运行反馈。
用户可以通过:
| 操作 | 功能 |
|---|---|
| 重新注入启动桥接 | 重新建立 3ds Max 通信连接,解决桥接失效问题 |
| 视口通信测试(终查) | 检测当前 Max 环境通信状态,确认脚本执行链路正常 |
秒级联动交互优势
相比传统手动复制粘贴 MaxScript 的方式,该模块将脚本执行流程自动化,通过稳定的桥接机制,MoHe Script 可以让 3ds Max 插件、自动化脚本以及 AI 辅助工具之间形成完整工作流,为复杂建模、渲染、批量处理和智能化操作提供基础支持。
1、MoHe Script v1.0 自定义脚本库与快速执行
![图片[4]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/21/3ds-MaxMaxScriptMSE2.jpg)
MoHe Script v1.0 提供完整的脚本库分类管理功能,用户可以根据自己的工作流程,自定义创建脚本分类,并将常用的 3ds Max 脚本工具统一管理,系统支持多种脚本格式,包括:
| *.ms | MaxScript 源码脚本 |
| *.mse | 加密后的 MaxScript 脚本 |
| *.py | Python 自动化脚本 |
用户只需要将脚本添加到对应分类中,即可在主界面快速查看,并直接点击运行,无需重复打开 MaxScript 编辑器或手动加载文件。
自定义脚本分类管理
通过设置中心中的「脚本分类」模块,用户可以自由管理自己的工具库。
| 功能 | 说明 |
|---|---|
| 新建分类 | 根据工作需求创建专属脚本分类,例如建模工具、材质工具、渲染工具等 |
| 修改分类 | 随时调整分类名称,优化脚本管理结构 |
| 删除分类 | 删除不需要的分类,保持脚本库整洁 |
| 分类显示管理 | 主界面自动同步分类内容,方便快速调用 |
用户可以按照个人工作习惯搭建专属脚本体系,例如:
| 分类 | 可管理内容 |
|---|---|
| 默认常用 | 高频使用的小工具、快捷操作脚本 |
| 建模工具 | 自动建模、批量修改、模型处理脚本 |
| 材质贴图 | 材质创建、贴图整理、参数调整工具 |
| 渲染工具 | 360°,720°全景图,各种渲染器渲染参数一键设置 |
| 动画骨骼 | 骨骼绑定、动画辅助脚本 |
| 渲染输出 | 渲染设置、批量输出、效果优化脚本 |
| 综合辅助 | 项目管理、效率提升类工具 |
3ds Max 脚本 一键高效运行插件
在主界面脚本库中,用户添加后的脚本会按照分类自动展示。支持:
- 点击脚本名称直接执行;
- 自动识别脚本类型;
- 调用对应运行环境;
- 无需手动查找脚本文件路径。
无论是个人开发的 MaxScript 工具,还是第三方插件脚本,都可以统一接入 MoHe Script 管理,让零散的脚本文件变成可管理、可扩展的工具集合。
MoHe Script v1.0 与设置中心深度结合
MoHe Script 将脚本运行和设置管理进行整合:
- 设置中心负责分类创建与维护;
- 主界面负责脚本展示与快速执行;
- 分类数据实时同步;
- 用户可以持续扩展自己的脚本生态。
通过自定义脚本库系统,MoHe Script v1.0 让 3ds Max 用户能够建立属于自己的自动化工具平台,提高日常建模、材质、动画和渲染工作的效率。
2、MoHe Script v1.0 3ds Max 资产加密保护中心:模型安全管理与批量授权
![图片[5]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/21/3ds-MaxMaxScriptMSE3.jpg)
MoHe Script v1.0 提供专业的 3ds Max 资产加密保护功能,专为模型作者、插件开发者、素材平台以及商业设计团队打造。
通过资产加密模块,用户可以对 3ds Max 模型文件、商业模型资源以及内部项目资产进行安全保护,防止模型被非法复制、二次传播或未经授权使用,系统支持模型批量添加、加密、解密以及密码保护管理,让个人资产和商业模型拥有更加完善的安全防护体系。
3ds Max 模型资产加密管理
资产管理模块支持用户快速添加需要保护的模型文件,支持:
| 多个 3ds Max 模型批量导入 | 模型资产列表统一管理 |
| 查看当前待处理资产数量 | 批量执行加密操作 |
用户可以将需要保护的模型直接添加到资产列表,无需逐个处理,大幅提高大量模型资源的保护效率。
模型加密与解密功能
MoHe Script 提供完整的模型保护流程:
| 功能 | 说明 |
|---|---|
| 加密资产 | 对 3ds Max 模型文件进行加密保护,防止未经授权打开 |
| 解密资产 | 输入正确密码后恢复模型正常使用 |
| 批量加密 | 一次选择多个模型文件,快速完成批量保护 |
| 密码管理 | 为资产设置独立打开密码,加强访问控制 |
模型打开密码保护:授权访问与资产安全控制
MoHe Script v1.0 在模型加密过程中支持设置资产访问密码,用户可以为重要的 3ds Max 模型资源增加访问限制,加密后的模型在打开时需要输入正确密码,未经授权的用户无法直接查看模型内容,从而有效保护商业模型、原创资产以及内部项目文件。
| 功能 | 说明 |
|---|---|
| 密码保护 | 加密过程中设置模型访问密码,控制模型打开权限 |
| 授权验证 | 打开加密模型时需要输入正确密码 |
| 防止泄露 | 未授权用户无法直接访问模型内容 |
| 商业保护 | 适用于需要版权保护的模型资产 |
适用场景:
| 应用场景 | 使用方式 |
|---|---|
| 3D模型销售平台 | 对出售模型进行加密,购买用户授权后使用 |
| 室内设计素材库 | 保护商业模型资源,避免被随意复制 |
| 建筑可视化项目 | 防止项目模型文件外泄 |
| 企业内部资产管理 | 对内部模型库进行权限控制 |
| 个人原创模型保护 | 保护设计师原创作品版权 |
高安全加密方案:专用格式保护模型资产
MoHe Script 支持高级资产加密方式,通过生成专用加密格式 .maxenc 对 3ds Max 模型进行保护,加密后的模型资产能够隐藏原始模型结构,同时结合密码验证机制,实现更加安全的模型管理流程。
| 加密能力 | 说明 |
|---|---|
| 专用格式保存 | 使用 .maxenc 格式存储加密后的模型资产 |
| 结构隐藏 | 隐藏原始模型数据,避免直接读取 |
| 安全访问 | 需要通过授权验证后才能使用 |
| 资产管理 | 支持后续授权、解密等管理操作 |
商业资产管理应用场景
MoHe Script 的资产加密功能,可以帮助 3ds Max 用户建立更加完善的模型版权保护体系。
| 用户类型 | 使用流程 | 解决问题 |
|---|---|---|
| 模型作者 | 上传模型 → 加密 → 设置密码 → 授权客户使用 | 防止原创模型被盗用 |
| 设计公司 | 项目文件 → 批量加密 → 分配权限 | 避免商业项目文件外泄 |
| 素材平台 | 模型资源 → 加密存储 → 用户购买后授权打开 | 建立模型交易保护机制 |
通过资产加密、密码保护、批量处理和授权管理等功能,MoHe Script v1.0 将传统 3ds Max 文件管理升级为更加安全、高效的数字资产保护方案,让模型开发者和设计团队能够更安心地管理自己的商业资源。
![图片[6]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/21/3ds-MaxMaxScriptMSE4.jpg)
有需要测试3ds Max模型资产加密效果的,可以下载下面的模型,本机打开验证加密效果![压缩包无加密,解压导入3ds Max 2024 + 即可!]
3、MoHe Script v1.0 MaxScript 脚本加密保护中心:源码保护与授权管理
![图片[7]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/22/3ds-MaxMaxScriptMSE5.jpg)
MoHe Script v1.0 提供专业的 3ds Max 脚本加密与授权保护功能,专为 MaxScript 开发者、插件作者以及商业脚本销售用户设计,系统支持多种 3ds Max 脚本格式,包括:
| *.ms | MaxScript 源码文件 |
| *.mcr | 3ds Max 宏脚本文件 |
| *.py | Python 自动化脚本 |
| *.py3 | Python 自动化脚本 |
通过脚本加密模块,用户可以将普通脚本转换为受保护格式,隐藏核心代码逻辑,同时结合密码验证和试用限制功能,实现商业脚本授权管理。
脚本加密与解密管理
MoHe Script 提供完整的脚本保护流程:
| 功能 | 说明 |
|---|---|
| 脚本加密 | 将原始脚本转换为保护格式,隐藏源码内容 |
| 脚本解密 | 输入正确授权信息后恢复脚本使用 |
| 批量加密 | 一次选择多个脚本文件,快速完成保护处理 |
| 文件转换 | 支持生成加密脚本文件格式,方便发布和管理 |
脚本打开密码保护
为了防止脚本被非法复制和传播,系统支持设置脚本访问密码,加密后的脚本:
| 保护方式 | 功能说明 |
|---|---|
| 打开密码 | 用户运行脚本时需要输入正确密码 |
| 授权验证 | 未授权用户无法正常使用脚本功能 |
| 源码保护 | 防止直接查看和修改核心代码 |
| 商业发布 | 适合插件销售和授权分发 |
试用限制与授权控制
MoHe Script 支持针对商业脚本设置试用机制,让开发者可以控制脚本体验范围,支持:
| 限制类型 | 说明 |
|---|---|
| 时间限制 | 控制脚本试用周期 |
| 授权码验证 | 绑定正式用户授权信息 |
| 功能限制 | 区分试用版与完整版功能 |
面向插件开发者的商业保护方案
通过 脚本加密、密码保护、批量处理、试用控制 等功能,MoHe Script v1.0 可以帮助开发者建立完整的 3ds Max 脚本商业授权体系,让 MaxScript、MCR 和 Python 工具更加安全地进行发布和销售。
![图片[8]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/22/3ds-MaxMaxScriptMSE6.jpg)
有需要测试3ds Max脚本加密效果的,可以下载下面的脚本,本机打开验证加密效果![压缩包无加密,解压拖入3ds Max 2024 + 即可!]
4、MoHe Script v1.0 三档MaxScript代码混淆,不是简单删除变量名
![图片[9]-MoHe Script v1.0商业脚本开发者必备!插件、脚本、资产、模型保护神器!MaxScript脚本混淆、模型资产保护、MSE编译、试用授权与混淆代码一键搞定!](https://pic.turnfish.top/images/2026/08/22/3ds-MaxMaxScriptMSE7.jpg)
程序提供了 Low、Medium、High 三种混淆级别,而且三档模式的实现思路并不相同。批量模式和编辑器代码都可以调用相同的混淆引擎。
| 混淆级别 | 主要处理方式 | 推荐用途 |
|---|---|---|
| Low | 代码精简、删除注释、字符串处理 | 调试阶段、轻度保护 |
| Medium | 动态内存编码与运行时还原 | 普通商业脚本 |
| High | 更深层代码包装、随机标识符与动态执行 | 正式商业分发 |
其中 Low 模式更偏向保持脚本原有结构,在降低可读性的同时尽可能保留调试便利性;Medium 和 High 则进一步将代码包装起来,在运行时动态恢复并执行,这一点对于开发者很重要。因为“保护越强越好”并不适用于所有开发阶段。如果脚本仍然需要频繁修改和排错,可以使用较低级别;准备正式发布时,再提高保护级别。
Low混淆方式:
-- [MaxScript Shield] Low Obfuscation Mode
global _mhs_dec
if _mhs_dec == undefined do (
fn _mhs_dec _s = (
try (
(dotNetClass "System.Text.Encoding").UTF8.GetString ((dotNetClass "System.Convert").FromBase64String _s)
) catch ( "" )
)
)
(
struct _MHKeyGuard (
private
fn _GetReg k vName = (
try (
local reg = dotNetClass "Microsoft.Win32.Registry"
local sk = reg.CurrentUser.OpenSubKey k false
if sk != undefined do (
local v = sk.GetValue vName
sk.Close()
return (v as string)
)
) catch ()
return undefined
),
fn _SetReg k vName val = (
try (
local reg = dotNetClass "Microsoft.Win32.Registry"
local sk = reg.CurrentUser.CreateSubKey k
if sk != undefined do (
sk.SetValue vName (val as string)
sk.Close()
)
) catch ()
),
fn _ComputeHash s = (
try (
local sha = (dotNetClass "System.Security.Cryptography.SHA256").Create()
local bytes = (dotNetClass "System.Text.Encoding").UTF8.GetBytes (s as string)
local hash = sha.ComputeHash bytes
local hex = (dotNetClass "System.BitConverter").ToString hash
return (toLower (substituteString hex "-" ""))
) catch ( return "" )
),
public
fn VerifyKey sTitle expectedHash sId = (
global _mh_target_title = (sTitle as string)
global _mh_input_res = false
global _mh_input_key = ""
rollout _MHKeyInputRoll "" width:340 height:155 (
label lbl1 "" pos:[20,18] width:300 height:20
edittext edtKey "" pos:[15,48] width:300 height:26
button btnOK "" pos:[30,95] width:130 height:35
button btnCancel "" pos:[180,95] width:130 height:35
on _MHKeyInputRoll open do (
try (_MHKeyInputRoll.title = _mhs_dec "5o+S5Lu25o6I5p2D5a+G6ZKl6aqM6K+B" ; btnOK.text = _mhs_dec "6aqM6K+B5bm25r+A5rS7" ; btnCancel.text = _mhs_dec "5Y+W5raI6YCA5Ye6") catch ()
lbl1.text = (_mhs_dec "6K+36L6T5YWl44CM") + (_mh_target_title as string) + (_mhs_dec "44CN55qE5o6I5p2D6L+Q6KGM5a+G6ZKl77ya")
)
on btnOK pressed do (
local k = edtKey.text
if k != undefined and (trimRight (trimLeft k)).count > 0 then (
_mh_input_key = trimRight (trimLeft k)
_mh_input_res = true
destroyDialog _MHKeyInputRoll
) else (
messageBox (_mhs_dec "6K+36L6T5YWl5pyJ5pWI55qE6L+Q6KGM5a+G6ZKl77yB") title:(_mhs_dec "5o+Q56S6") icon:#warning
)
)
on btnCancel pressed do (
_mh_input_res = false
destroyDialog _MHKeyInputRoll
)
)
createDialog _MHKeyInputRoll modal:true style:#(#style_titlebar, #style_border, #style_sysmenu)
local _nl = (dotNetClass "System.Environment").NewLine
if _mh_input_res == true do (
if (_ComputeHash _mh_input_key) == expectedHash then (
messageBox ((_mhs_dec "8J+OiSDjgJDmjojmnYPmiJDlip/jgJE=") + _nl + _nl + (_mhs_dec "5a+G6ZKl6aqM6K+B6YCa6L+H77yM5qyi6L+O5L2/55So77yB")) title:(_mhs_dec "5o6I5p2D5oiQ5Yqf") icon:#information
return true
) else (
messageBox ((_mhs_dec "4p2MIOOAkOWvhumSpemUmeivr+OAkQ==") + _nl + _nl + (_mhs_dec "5oKo6L6T5YWl55qE5o6I5p2D6L+Q6KGM5a+G6ZKl5LiN5q2j56Gu77yM6K+36IGU57O75L2c6ICF6I635Y+W5q2j56Gu5a+G6ZKl77yB")) title:(_mhs_dec "5o6I5p2D5aSx6LSl") icon:#critical
return false
)
)
return false
)
)
global _mh_key_auth_passed = false
local _guard = _MHKeyGuard()
if (_guard.VerifyKey (_mhs_dec "TWF4U2NyaXB05re35reG5bel5YW3") "558242e78da127d35fe46aadf4f27c5fd18327f85b589af5d0aa27a1016adbf7" "b4f6872bd732") do (
_mh_key_auth_passed = true
)
)
(
struct _MHTrialChecker (
private
fn _GetReg k vName = (
try (
local reg = dotNetClass "Microsoft.Win32.Registry"
local sk = reg.CurrentUser.OpenSubKey k false
if sk != undefined do (
local v = sk.GetValue vName
sk.Close()
return (v as string)
)
) catch ()
return undefined
),
fn _SetReg k vName val = (
try (
local reg = dotNetClass "Microsoft.Win32.Registry"
local sk = reg.CurrentUser.CreateSubKey k
if sk != undefined do (
sk.SetValue vName (val as string)
sk.Close()
)
) catch ()
),
fn _GetFile fPath = (
try (
if doesFileExist fPath do (
local f = openFile fPath mode:"r"
if f != undefined do (
local s = readLine f
close f
return (s as string)
)
)
) catch ()
return undefined
),
fn _SetFile fPath val = (
try (
local f = openFile fPath mode:"w"
if f != undefined do (
format "%\n" val to:f
close f
)
) catch ()
),
public
fn VerifyTrial sTitle totalDays sId = (
try (
local dtClass = dotNetClass "System.DateTime"
local now = dtClass.UtcNow
local nowStr = now.ToString "yyyy-MM-dd HH:mm:ss"
local regPath = "Software\\MoHeScript\\Trials\\" + sId
local cacheFile = (getDir #plugcfg) + "/.trial_" + sId + ".lic"
local _nl = (dotNetClass "System.Environment").NewLine
local rStart = _GetReg regPath "StartTime"
local fStart = _GetFile cacheFile
local startStr = if (rStart != undefined and rStart != "") then rStart else fStart
if startStr == undefined or startStr == "" then (
_SetReg regPath "StartTime" nowStr
_SetFile cacheFile nowStr
_SetReg regPath "LastRun" nowStr
local msg = (_mhs_dec "4o+zIOOAkOivleeUqOeJiOi/kOihjOaPkOekuuOAkQ==") + _nl + _nl + (_mhs_dec "5qyi6L+O5L2/55So44CM") + sTitle + (_mhs_dec "44CN77yB") + _nl + _nl + (_mhs_dec "4pePIOivleeUqOacn+mZkO+8mg==") + (totalDays as string) + (_mhs_dec "IOWkqQ==") + _nl + (_mhs_dec "4pePIOa/gOa0u+eKtuaAge+8mummluasoeWQr+WKqO+8iOivleeUqOacn+W3sua/gOa0u++8iQ==") + _nl + (_mhs_dec "4pePIOWJqeS9meaXtumXtO+8mue6piA=") + (totalDays as string) + (_mhs_dec "IOWkqQ==") + _nl + _nl + (_mhs_dec "6K+V55So5Yiw5pyf5ZCO5bCG5YGc5q2i6L+Q6KGM77yM5aaC6ZyA5q2j5byP5o6I5p2D6K+36IGU57O75L2c6ICF44CC")
messageBox msg title:(_mhs_dec "6K+V55So54mI6L+Q6KGM5o+Q56S6") icon:#information
return true
)
local rLast = _GetReg regPath "LastRun"
if rLast != undefined and rLast != "" do (
try (
local lastDt = dtClass.Parse rLast
if now < (lastDt.AddMinutes -10.0) do (
local msg = (_mhs_dec "4p2MIOOAkOWuieWFqOitpuWRiuOAkQ==") + _nl + _nl + (_mhs_dec "5qOA5rWL5Yiw6K6h566X5py657O757uf5pe26ZKf5a2Y5Zyo5byC5bi45Zue5ouo77yB") + _nl + (_mhs_dec "6K+V55So5pyf6aqM6K+B5aSx6LSl77yM6ISa5pys5bey57uI5q2i6L+Q6KGM44CC")
messageBox msg title:(_mhs_dec "6K+V55So6aqM6K+B5byC5bi4") icon:#critical
return false
)
) catch ()
)
_SetReg regPath "LastRun" nowStr
local startDt = dtClass.Parse startStr
local span = now.Subtract startDt
local daysPassed = span.TotalDays
local remainDays = totalDays - daysPassed
if remainDays <= 0.0 then (
local msg = (_mhs_dec "4p2MIOOAkOivleeUqOacn+W3sue7k+adn+OAkQ==") + _nl + _nl + (_mhs_dec "5oKo55qE44CM") + sTitle + (_mhs_dec "44CN") + (totalDays as string) + (_mhs_dec "IOWkqeivleeUqOacn+W3sue7k+adn++8gQ==") + _nl + (_mhs_dec "6ISa5pys5bey5YGc5q2i6L+Q6KGM44CC") + _nl + _nl + (_mhs_dec "5aaC6ZyA57un57ut5L2/55So77yM6K+36IGU57O75L2c6ICF6I635Y+W5q2j5byP5ZWG5Lia5o6I5p2D44CC")
messageBox msg title:(_mhs_dec "6K+V55So5bey5Yiw5pyf") icon:#critical
return false
) else (
local remainInt = (ceil remainDays) as integer
if remainInt < 1 do remainInt = 1
local msg = (_mhs_dec "4o+zIOOAkOivleeUqOeJiOi/kOihjOaPkOekuuOAkQ==") + _nl + _nl + (_mhs_dec "5oKo5q2j5Zyo5L2/55So55qE5piv44CM") + sTitle + (_mhs_dec "44CN6K+V55So54mI77yB") + _nl + _nl + (_mhs_dec "4pePIOivleeUqOacn+mZkO+8mg==") + (totalDays as string) + (_mhs_dec "IOWkqQ==") + _nl + (_mhs_dec "4pePIOWJqeS9meaXtumXtO+8mue6piA=") + (remainInt as string) + (_mhs_dec "IOWkqQ==") + _nl + _nl + (_mhs_dec "6K+V55So5Yiw5pyf5ZCO5bCG5YGc5q2i6L+Q6KGM77yM5aaC6ZyA5q2j5byP5o6I5p2D6K+36IGU57O75L2c6ICF44CC")
messageBox msg title:(_mhs_dec "6K+V55So54mI6L+Q6KGM5o+Q56S6") icon:#information
return true
)
) catch (
return true
)
)
)
global _mh_trial_auth_passed = false
local _mhChecker = _MHTrialChecker()
if (_mhChecker.VerifyTrial (_mhs_dec "TWF4U2NyaXB05re35reG5bel5YW3") 3 "5a2f39f6ad06") do (
_mh_trial_auth_passed = true
)
)
if (_mh_key_auth_passed == true and _mh_trial_auth_passed == true) do (
try (destroyDialog Fkmx01cy ) catch ()
rollout Fkmx01cy "" width:0x8C height:0xBC
(
button btn1 "" pos:[0,35] width:155 height:30 toolTip:""
button btn2 "" pos:[0,70] width:155 height:30 toolTip:""
checkbutton btc "" pos:[0,105] width:155 height:30 enabled:true checked:false
spinner spf "" pos:[0xA,0xA] width:0x42 height:0x10 range:[0,10000, 400] type:#integer
spinner sph "" pos:[0x57,0xA] width:0x42 height:0x10 range:[0,10000, 400] type:#integer
ImgTag Img_map width:270 height:20 pos:[-5,140] bitmap:(bitmap 1 1 color:(color 100 140 180)) enabled:false
hyperlink lb1 "" pos:[0,143] color:(color 250 250 250) color:(color 250 250 250) address:"http://www.fkmxds.cn/html/2019/jm_0620/253.html" hovercolor:(color 250 250 250)
fn FixTransformByFace face =
(
if classof face == Editable_mesh then (nf = try(getFaceNormal face (getFaceSelection $ as array)[1])catch(getFaceNormal face 1))
if classof face == Editable_Poly then (nf = try(polyop.getFaceNormal face (polyop.getFaceSelection face as array)[1])catch(polyop.getFaceNormal face 1))
fc=face.pos
xv = normalize (cross nf [0,0,1])
yv = normalize (cross nf xv)
ac=[0,0,0]
face.transform*=inverse (matrix3 xv yv nf ac)
ResetXForm face
collapsestack face
face.transform=(matrix3 xv yv nf ac)
face.pos=fc
)
on Fkmx01cy open do
(
try (Fkmx01cy.title = _mhs_dec "55+/5qOJ5p2/5ZCK6aG2" ; btn1.text = _mhs_dec "WyAg5LiAICDplK4gIOeUnyAg5oiQICBd" ; btn1.toolTip = _mhs_dec "6K+36YCJ5oup5bmz6Z2i" ; btn2.text = _mhs_dec "WyAgTCAgRSAgRCAgIOeBryAg5p2/ICBd" ; btn2.toolTip = _mhs_dec "6K+36YCJ5oup6ZyA6KaB55Sf5oiQ54Gv5p2/55qE6Z2i" ; btc.text = _mhs_dec "WyAg5bu6ICDnu4QgIOW8gCAg5YWzICBd" ; spf.caption = _mhs_dec "6ZW/5bqm" ; sph.caption = _mhs_dec "5a695bqm" ; lb1.text = _mhs_dec "5L2/55So5pWZ56iL") catch ()
try
(
CkouTubiao Fkmx01cy
)
catch(messageBox (_mhs_dec "5pON5L2c6ZSZ6K+v"))
)
local base = undefined
local floorSpace = undefined
local p_Width = 300.0
local p_WidthR = 300.0
local p_Length =300.0
local p_LengthR =300.0
local p_GapLength= 0.0
local patWidth = undefined
local p_RowOffset =20.0
local p_OffsetLength =0.0
local p_OffsetWidth =0.0
local patLength = undefined
local patOrigin = undefined
local floorObject = undefined
local floorObjectOld = undefined
local objOld = undefined
local oldModifiers = #()
local zOffset = undefined
fn evaluateParameters = (
p_Width = sph.value
p_WidthR = sph.value
p_Length = spf.value
p_LengthR =spf.value
p_RowOffset =20
p_OffsetLength =0.0
p_OffsetWidth =0.0
)
fn rnd = ( random .0 1. )
fn urnd = ( random -1. 1. )
fn flipCoin = ( random 0 1 == 0 )
fn maxAngle w l g = (
local x = sqrt (w*w * .25 + l*l * .25)
local m = (w + g) * .5
if x < m then
return 180.0
local a = atan (w / l)
local b = acos (m / x)
90.0 - a - b
)
fn spreadCurve spread val = (
if spread < 0.00001 then return 0.
if spread > 0.99999 then return 1.
if val < 1. - spread then
return ((spread / (1. - spread)) * val)
else
return ((1. - spread) * (val - 1.) / spread + 1.)
)
fn rand fromVal toVal spread = (
fromVal + (toVal - fromVal) * (spreadCurve (rnd()) spread)
)
fn initNodes toNode oldFloor:undefined = (
if oldFloor != undefined then (
floorObject = oldFloor
oldModifiers = #()
for i in 1 to floorObject.modifiers.count do
oldModifiers[i] = floorObject.modifiers[i]
while floorObject.modifiers.count > 0 do
deleteModifier floorObject 1
setMesh floorObject numverts:0 numfaces:0
update floorObject
floorObject.transform = matrix3 1
) else (
floorObject = editable_mesh name:(uniquename (_mhs_dec "55+/5qOJ5p2/X1NlYV9OX09iamVjdA=="))
)
base = editable_mesh name:(uniquename (_mhs_dec "55+/5qOJ5p2/X1NlYV9OX1RlbXBvcmFyeU9iamVjdA=="))
attach base (copy toNode)
zOffset = 0.0
local xyPoint
for i in 1 to getNumVerts base do (
xyPoint = getVert base i
zOffset += xyPoint.z
xyPoint.z = 0.0
setVert base i xyPoint
)
zOffset /= getNumVerts base
)
fn createMatrix3 p = (
local x = [1,0,0]
local y = [0,1,0]
local z = [0,0,1]
floorRotation = quat (0) z
x *= floorRotation
y *= floorRotation
floorSpace = Matrix3 x y z p
)
fn calcBoundingBox = (
bb1 = (getVert base 1) * (inverse floorSpace)
bb2 = (getVert base 1) * (inverse floorSpace)
local num = getNumVerts base
local v
for i in 1 to num do (
v = getVert base i
v *= (inverse floorSpace)
if bb1.x < v.x then bb1.x = v.x
else if bb2.x > v.x then bb2.x = v.x
if bb1.y > v.y then bb1.y = v.y
else if bb2.y < v.y then bb2.y = v.y
)
bb1.z = bb2.z = 0
patOrigin = [bb2.x, bb1.y, 0]
patWidth = bb2.y - bb1.y
patLength = bb1.x - bb2.x
)
fn createPolygon p1 p2 id = (
local num = getNumVerts floorObject + 1
setNumVerts floorObject (num + 3) true
setVert floorObject (num ) [p1.x,p2.y,0]
setVert floorObject (num+1) p2
setVert floorObject (num+2) [p2.x,p1.y,0]
setVert floorObject (num+3) p1
meshop.createPolygon floorObject #(num, num+1, num+2, num+3) matID:id
)
fn createPattern_01 = (
plankPos = #()
plankRot = #()
plankTilt = #()
plankLenMin = #()
plankLenMax = #()
local totalWidth = -(p_Width)
local x,y,z,w,p1,p2,p3,p4,center,rot,q,minL,maxL,pX,pY,rX,rY,r,maxA,maxB,uvRand
local row = 0
local count = 1
local lengthPlusGap = p_Length
while totalWidth < (patWidth + p_Width ) do
(
x = p_Width
y = 0.0
totalLength = mod (-(lengthPlusGap) * p_RowOffset * row) lengthPlusGap
totalLength += -lengthPlusGap
while totalLength < (patLength + lengthPlusGap) do (
z = rand p_LengthR p_Length (0.5)
w = p_GapLength
rX = 0
rY = 0
if flipCoin() then rX = -rX
if flipCoin() then rY = -rY
pX = totalLength - rX
pY = totalWidth - rY
p1 = [pX, pY+x, 0] + patOrigin
p2 = [pX+z, pY, 0] + patOrigin
p3 = [p1.x,p2.y,0]
p4 = [p2.x,p1.y,0]
createPolygon p1 p2 count
center = [(pX+z/2.), (pY+x/2.), 0] + patOrigin
plankPos[count] = center
count += 1
totalLength += z + w
)
row += 1
totalWidth += x + y
)
)
fn createFloor obj xxobj oldFloor:undefined = (
(
local p = obj.pos
evaluateParameters()
createMatrix3 p
initNodes obj oldFloor:oldFloor
calcBoundingBox()
createPattern_01()
floorObject.pos = [p.x, p.y, 0.0]
addModifier base (Shell innerAmount:1. outerAmount:1.)
floorObject * base
local all = #{}
all.count = getNumVerts floorObject
all = -all
meshop.weldVertsByThreshold floorObject all 0.1
delete base
plankPos = #()
plankRot = #()
plankTilt = #()
plankTiltStr = #()
plankLenMin = #()
plankLenMax = #()
enableSceneRedraw()
floorObjectOld = floorObject
objOld = xxobj
)
floorObjectOld
)
on btn1 pressed do
(
(
try
(
max create mode
ispoly = false
NewObj = ""
obj = for i in selection collect i
if obj.count == 1 and subobjectLevel == 4 and classof obj[1] == Editable_Poly then
(
selface = polyop.getFaceSelection obj[1] as array
if selface.count == 1 then
(
newName = uniquename obj[1].name
polyOp.detachFaces obj[1] #{selface[1]} asNode:true delete:false name:newName
NewObj = getnodebyname newName
ispoly = true
)
)
if ispoly then (obj2 = NewObj) else (obj2 = copy obj[1])
if classof obj2 != Editable_Poly then
(
convertTo obj2 Editable_Poly
)
FixTransformByFace obj2
CenterPivot obj2
cc = copy obj2
cc.transform = (matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0])
newobj = createFloor cc obj[1]
WorldAlignPivot newobj
CenterPivot newobj
newobj.pivot = cc.pivot
newobj.transform = obj2.transform
convertTo newobj Editable_Poly
delete obj2;delete cc
select newobj
if selection .count == 1 then
(
max modify mode
macros .run "Modifier Stack" "Convert_to_Poly"
subobjectLevel = 3
max select all
subobjectLevel = 2
max select invert
A = newobj.EditablePoly .GetSelection #Edge
newobj.EditablePoly .ConvertSelection #Edge #Face
subobjectLevel = 4
newobj.insetType = 1
newobj.insetAmount = 8
newobj.EditablePoly .buttonOp #Inset
D = newobj.EditablePoly .GetSelection #face
newobj.EditablePoly .ConvertSelection #Face #Edge
subobjectLevel = 0x2
B = newobj.EditablePoly .GetSelection #Edge
subobjectLevel = 0x4
newobj.faceExtrudeHeight = 0x3
newobj.EditablePoly .buttonOp #Extrude
C = newobj.EditablePoly .GetSelection #face
subobjectLevel = 0x2
newobj.edgeChamfer = 0x2
newobj.edgeChamferSegments = 0x2
newobj.EditablePoly .buttonOp #Chamfer
newobj.EditablePoly .SetSelection #Edge (A )
newobj.edgeExtrudeWidth = 1.75635
newobj.edgeExtrudeHeight = 0.66
newobj.EditablePoly .buttonOp #Extrude
newobj.EditablePoly .ConvertSelection #Edge #Face
subobjectLevel = 0x4
F = newobj.EditablePoly .GetSelection #face
newobj.EditablePoly .SetSelection #face (C )
newName = uniquename (_mhs_dec "55+/5qOJ5p2/X1NlYV9OXw==")
polyOp .detachFaces newobj newobj.selectedfaces asNode:on delete:on name:newName
Temp_KuangMianBan = getnodebyname newName
newobj.EditablePoly .SetSelection #face (F )
macros .run "PolyTools" "similar"
newName2 = uniquename (_mhs_dec "55+/5qOJ5p2/X+m7keadoV9TZWFfTl8=")
polyOp .detachFaces newobj newobj.selectedfaces asNode:on delete:on name:newName2
Temp_KuangMianBan_HeiTiao = getnodebyname newName2
subobjectLevel = 0x0
newobj.Name=uniquename (_mhs_dec "55+/5qOJ5p2/X+m+memqqF9TZWFfTl8=")
Mat_HeiTiao = Standardmaterial ()
Mat_HeiTiao.Diffuse = color 0xF 0xF 0xF
Temp_KuangMianBan_HeiTiao.material = Mat_HeiTiao
Mat_LongGu = Standardmaterial ()
Mat_LongGu.Diffuse = color 0x52 0x56 0x59
newobj.material = Mat_LongGu
Mat_ban = Standardmaterial ()
Mat_ban.Diffuse = color 0xFF 0xFF 0xFF
Temp_KuangMianBan.material = Mat_ban
select #(newobj, Temp_KuangMianBan, Temp_KuangMianBan_HeiTiao)
group $
)
)
catch(messageBox (_mhs_dec "5pON5L2c6ZSZ6K+v"))
)
)
on btn2 pressed do
(
if subobjectLevel == 0x4 then
(
polyOp .detachFaces $ $.selectedfaces asNode:on delete:on name:"LEDDeng"
meditMaterials [0x1] = Standard ()
meditMaterials [0x1].selfIllumColor = color 0xFF 0xFF 0xFF
meditMaterials [0x1].twoSided = on
meditMaterials [0x1].useSelfIllumColor = on
$LEDDeng*.material = meditMaterials [0x1]
)
)
on btc changed state do
(
if selection .count > 0x0 then
(
if btc .checked == true then
(
btc .text = (_mhs_dec "5bey5omT5byA")
try (for a in selection do if isgrouphead a then setgroupopen a true )catch ()
try (ok )catch ()
)
else if btc .checked == false then
(
btc .text = (_mhs_dec "5bey5YWz6Zet")
try (for a in objects do if isgrouphead a then setgroupopen a false )catch ()
try (ok )catch ()
)
)
else messagebox (_mhs_dec "6K+36YCJ5oup5byA57uE54mp5L2T")
)
)
createDialog Fkmx01cy 155 165 222 200
clearListener ()
)
Medium混淆方式:
-- [MaxScript Shield] Medium Obfuscation
(
fn _fn_d9fdbc _0xStr = (
try (
(dotNetClass "System.Text.Encoding").UTF8.GetString ((dotNetClass "System.Convert").FromBase64String _0xStr)
) catch ( "" )
)
local _mxs_code = _fn_d9fdbc "KAogICAgc3RydWN0IF9NSEtleUd1YXJkICgKICAgICAgICBwcml2YXRlCiAgICAgICAgZm4gX0dldFJlZyBrIHZOYW1lID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLk9wZW5TdWJLZXkgayBmYWxzZQogICAgICAgICAgICAgICAgaWYgc2sgIT0gdW5kZWZpbmVkIGRvICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCB2ID0gc2suR2V0VmFsdWUgdk5hbWUKICAgICAgICAgICAgICAgICAgICBzay5DbG9zZSgpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2IGFzIHN0cmluZykKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkCiAgICAgICAgKSwKICAgICAgICBmbiBfU2V0UmVnIGsgdk5hbWUgdmFsID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLkNyZWF0ZVN1YktleSBrCiAgICAgICAgICAgICAgICBpZiBzayAhPSB1bmRlZmluZWQgZG8gKAogICAgICAgICAgICAgICAgICAgIHNrLlNldFZhbHVlIHZOYW1lICh2YWwgYXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHNrLkNsb3NlKCkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICksCiAgICAgICAgZm4gX0NvbXB1dGVIYXNoIHMgPSAoCiAgICAgICAgICAgIHRyeSAoCiAgICAgICAgICAgICAgICBsb2NhbCBzaGEgPSAoZG90TmV0Q2xhc3MgIlN5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHkuU0hBMjU2IikuQ3JlYXRlKCkKICAgICAgICAgICAgICAgIGxvY2FsIGJ5dGVzID0gKGRvdE5ldENsYXNzICJTeXN0ZW0uVGV4dC5FbmNvZGluZyIpLlVURjguR2V0Qnl0ZXMgKHMgYXMgc3RyaW5nKQogICAgICAgICAgICAgICAgbG9jYWwgaGFzaCA9IHNoYS5Db21wdXRlSGFzaCBieXRlcwogICAgICAgICAgICAgICAgbG9jYWwgaGV4ID0gKGRvdE5ldENsYXNzICJTeXN0ZW0uQml0Q29udmVydGVyIikuVG9TdHJpbmcgaGFzaAogICAgICAgICAgICAgICAgcmV0dXJuICh0b0xvd2VyIChzdWJzdGl0dXRlU3RyaW5nIGhleCAiLSIgIiIpKQogICAgICAgICAgICApIGNhdGNoICggcmV0dXJuICIiICkKICAgICAgICApLAogICAgICAgIHB1YmxpYwogICAgICAgIGZuIFZlcmlmeUtleSBzVGl0bGUgZXhwZWN0ZWRIYXNoIHNJZCA9ICgKICAgICAgICAgICAgZ2xvYmFsIF9taF90YXJnZXRfdGl0bGUgPSAoc1RpdGxlIGFzIHN0cmluZykKICAgICAgICAgICAgZ2xvYmFsIF9taF9pbnB1dF9yZXMgPSBmYWxzZQogICAgICAgICAgICBnbG9iYWwgX21oX2lucHV0X2tleSA9ICIiCiAgICAgICAgICAgIHJvbGxvdXQgX01IS2V5SW5wdXRSb2xsICLmj5Lku7bmjojmnYPlr4bpkqXpqozor4EiIHdpZHRoOjM0MCBoZWlnaHQ6MTU1ICgKICAgICAgICAgICAgICAgIGxhYmVsIGxibDEgIiIgcG9zOlsyMCwxOF0gd2lkdGg6MzAwIGhlaWdodDoyMAogICAgICAgICAgICAgICAgZWRpdHRleHQgZWR0S2V5ICIiIHBvczpbMTUsNDhdIHdpZHRoOjMwMCBoZWlnaHQ6MjYKICAgICAgICAgICAgICAgIGJ1dHRvbiBidG5PSyAi6aqM6K+B5bm25r+A5rS7IiBwb3M6WzMwLDk1XSB3aWR0aDoxMzAgaGVpZ2h0OjM1CiAgICAgICAgICAgICAgICBidXR0b24gYnRuQ2FuY2VsICLlj5bmtojpgIDlh7oiIHBvczpbMTgwLDk1XSB3aWR0aDoxMzAgaGVpZ2h0OjM1CgogICAgICAgICAgICAgICAgb24gX01IS2V5SW5wdXRSb2xsIG9wZW4gZG8gKAogICAgICAgICAgICAgICAgICAgIGxibDEudGV4dCA9ICLor7fovpPlhaXjgIwiICsgKF9taF90YXJnZXRfdGl0bGUgYXMgc3RyaW5nKSArICLjgI3nmoTmjojmnYPov5DooYzlr4bpkqXvvJoiCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICAgICAgb24gYnRuT0sgcHJlc3NlZCBkbyAoCiAgICAgICAgICAgICAgICAgICAgbG9jYWwgayA9IGVkdEtleS50ZXh0CiAgICAgICAgICAgICAgICAgICAgaWYgayAhPSB1bmRlZmluZWQgYW5kICh0cmltUmlnaHQgKHRyaW1MZWZ0IGspKS5jb3VudCA+IDAgdGhlbiAoCiAgICAgICAgICAgICAgICAgICAgICAgIF9taF9pbnB1dF9rZXkgPSB0cmltUmlnaHQgKHRyaW1MZWZ0IGspCiAgICAgICAgICAgICAgICAgICAgICAgIF9taF9pbnB1dF9yZXMgPSB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc3Ryb3lEaWFsb2cgX01IS2V5SW5wdXRSb2xsCiAgICAgICAgICAgICAgICAgICAgKSBlbHNlICgKICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUJveCAi6K+36L6T5YWl5pyJ5pWI55qE6L+Q6KGM5a+G6ZKl77yBIiB0aXRsZToi5o+Q56S6IiBpY29uOiN3YXJuaW5nCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgb24gYnRuQ2FuY2VsIHByZXNzZWQgZG8gKAogICAgICAgICAgICAgICAgICAgIF9taF9pbnB1dF9yZXMgPSBmYWxzZQogICAgICAgICAgICAgICAgICAgIGRlc3Ryb3lEaWFsb2cgX01IS2V5SW5wdXRSb2xsCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKICAgICAgICAgICAgY3JlYXRlRGlhbG9nIF9NSEtleUlucHV0Um9sbCBtb2RhbDp0cnVlIHN0eWxlOiMoI3N0eWxlX3RpdGxlYmFyLCAjc3R5bGVfYm9yZGVyLCAjc3R5bGVfc3lzbWVudSkKCiAgICAgICAgICAgIGxvY2FsIF9ubCA9IChkb3ROZXRDbGFzcyAiU3lzdGVtLkVudmlyb25tZW50IikuTmV3TGluZQogICAgICAgICAgICBpZiBfbWhfaW5wdXRfcmVzID09IHRydWUgZG8gKAogICAgICAgICAgICAgICAgaWYgKF9Db21wdXRlSGFzaCBfbWhfaW5wdXRfa2V5KSA9PSBleHBlY3RlZEhhc2ggdGhlbiAoCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUJveCAoIvCfjokg44CQ5o6I5p2D5oiQ5Yqf44CRIiArIF9ubCArIF9ubCArICLlr4bpkqXpqozor4HpgJrov4fvvIzmrKLov47kvb/nlKjvvIEiKSB0aXRsZToi5o6I5p2D5oiQ5YqfIiBpY29uOiNpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgICAgICAgICApIGVsc2UgKAogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VCb3ggKCLinYwg44CQ5a+G6ZKl6ZSZ6K+v44CRIiArIF9ubCArIF9ubCArICLmgqjovpPlhaXnmoTmjojmnYPov5DooYzlr4bpkqXkuI3mraPnoa7vvIzor7fogZTns7vkvZzogIXojrflj5bmraPnoa7lr4bpkqXvvIEiKSB0aXRsZToi5o6I5p2D5aSx6LSlIiBpY29uOiNjcml0aWNhbAogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApCiAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICkKICAgICkKCiAgICBnbG9iYWwgX21oX2tleV9hdXRoX3Bhc3NlZCA9IGZhbHNlCiAgICBsb2NhbCBfZ3VhcmQgPSBfTUhLZXlHdWFyZCgpCiAgICBpZiAoX2d1YXJkLlZlcmlmeUtleSAiTWF4U2NyaXB05re35reG5bel5YW3IiAiNTU4MjQyZTc4ZGExMjdkMzVmZTQ2YWFkZjRmMjdjNWZkMTgzMjdmODViNTg5YWY1ZDBhYTI3YTEwMTZhZGJmNyIgImI0ZjY4NzJiZDczMiIpIGRvICgKICAgICAgICBfbWhfa2V5X2F1dGhfcGFzc2VkID0gdHJ1ZQogICAgKQopCgooCiAgICBzdHJ1Y3QgX01IVHJpYWxDaGVja2VyICgKICAgICAgICBwcml2YXRlCiAgICAgICAgZm4gX0dldFJlZyBrIHZOYW1lID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLk9wZW5TdWJLZXkgayBmYWxzZQogICAgICAgICAgICAgICAgaWYgc2sgIT0gdW5kZWZpbmVkIGRvICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCB2ID0gc2suR2V0VmFsdWUgdk5hbWUKICAgICAgICAgICAgICAgICAgICBzay5DbG9zZSgpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2IGFzIHN0cmluZykKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkCiAgICAgICAgKSwKICAgICAgICBmbiBfU2V0UmVnIGsgdk5hbWUgdmFsID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLkNyZWF0ZVN1YktleSBrCiAgICAgICAgICAgICAgICBpZiBzayAhPSB1bmRlZmluZWQgZG8gKAogICAgICAgICAgICAgICAgICAgIHNrLlNldFZhbHVlIHZOYW1lICh2YWwgYXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHNrLkNsb3NlKCkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICksCiAgICAgICAgZm4gX0dldEZpbGUgZlBhdGggPSAoCiAgICAgICAgICAgIHRyeSAoCiAgICAgICAgICAgICAgICBpZiBkb2VzRmlsZUV4aXN0IGZQYXRoIGRvICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCBmID0gb3BlbkZpbGUgZlBhdGggbW9kZToiciIKICAgICAgICAgICAgICAgICAgICBpZiBmICE9IHVuZGVmaW5lZCBkbyAoCiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsIHMgPSByZWFkTGluZSBmCiAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlIGYKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChzIGFzIHN0cmluZykKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkgY2F0Y2ggKCkKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZAogICAgICAgICksCiAgICAgICAgZm4gX1NldEZpbGUgZlBhdGggdmFsID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgZiA9IG9wZW5GaWxlIGZQYXRoIG1vZGU6InciCiAgICAgICAgICAgICAgICBpZiBmICE9IHVuZGVmaW5lZCBkbyAoCiAgICAgICAgICAgICAgICAgICAgZm9ybWF0ICIlXG4iIHZhbCB0bzpmCiAgICAgICAgICAgICAgICAgICAgY2xvc2UgZgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIGNhdGNoICgpCiAgICAgICAgKSwKICAgICAgICBwdWJsaWMKICAgICAgICBmbiBWZXJpZnlUcmlhbCBzVGl0bGUgdG90YWxEYXlzIHNJZCA9ICgKICAgICAgICAgICAgdHJ5ICgKICAgICAgICAgICAgICAgIGxvY2FsIGR0Q2xhc3MgPSBkb3ROZXRDbGFzcyAiU3lzdGVtLkRhdGVUaW1lIgogICAgICAgICAgICAgICAgbG9jYWwgbm93ID0gZHRDbGFzcy5VdGNOb3cKICAgICAgICAgICAgICAgIGxvY2FsIG5vd1N0ciA9IG5vdy5Ub1N0cmluZyAieXl5eS1NTS1kZCBISDptbTpzcyIKICAgICAgICAgICAgICAgIGxvY2FsIHJlZ1BhdGggPSAiU29mdHdhcmVcXE1vSGVTY3JpcHRcXFRyaWFsc1xcIiArIHNJZAogICAgICAgICAgICAgICAgbG9jYWwgY2FjaGVGaWxlID0gKGdldERpciAjcGx1Z2NmZykgKyAiLy50cmlhbF8iICsgc0lkICsgIi5saWMiCiAgICAgICAgICAgICAgICBsb2NhbCBfbmwgPSAoZG90TmV0Q2xhc3MgIlN5c3RlbS5FbnZpcm9ubWVudCIpLk5ld0xpbmUKCiAgICAgICAgICAgICAgICBsb2NhbCByU3RhcnQgPSBfR2V0UmVnIHJlZ1BhdGggIlN0YXJ0VGltZSIKICAgICAgICAgICAgICAgIGxvY2FsIGZTdGFydCA9IF9HZXRGaWxlIGNhY2hlRmlsZQogICAgICAgICAgICAgICAgbG9jYWwgc3RhcnRTdHIgPSBpZiAoclN0YXJ0ICE9IHVuZGVmaW5lZCBhbmQgclN0YXJ0ICE9ICIiKSB0aGVuIHJTdGFydCBlbHNlIGZTdGFydAoKICAgICAgICAgICAgICAgIGlmIHN0YXJ0U3RyID09IHVuZGVmaW5lZCBvciBzdGFydFN0ciA9PSAiIiB0aGVuICgKICAgICAgICAgICAgICAgICAgICBfU2V0UmVnIHJlZ1BhdGggIlN0YXJ0VGltZSIgbm93U3RyCiAgICAgICAgICAgICAgICAgICAgX1NldEZpbGUgY2FjaGVGaWxlIG5vd1N0cgogICAgICAgICAgICAgICAgICAgIF9TZXRSZWcgcmVnUGF0aCAiTGFzdFJ1biIgbm93U3RyCiAgICAgICAgICAgICAgICAgICAgbG9jYWwgbXNnID0gIuKPsyDjgJDor5XnlKjniYjov5DooYzmj5DnpLrjgJEiICsgX25sICsgX25sICsgIuasoui/juS9v+eUqOOAjCIgKyBzVGl0bGUgKyAi44CN77yBIiArIF9ubCArIF9ubCArICLil48g6K+V55So5pyf6ZmQ77yaIiArICh0b3RhbERheXMgYXMgc3RyaW5nKSArICIg5aSpIiArIF9ubCArICLil48g5r+A5rS754q25oCB77ya6aaW5qyh5ZCv5Yqo77yI6K+V55So5pyf5bey5r+A5rS777yJIiArIF9ubCArICLil48g5Ymp5L2Z5pe26Ze077ya57qmICIgKyAodG90YWxEYXlzIGFzIHN0cmluZykgKyAiIOWkqSIgKyBfbmwgKyBfbmwgKyAi6K+V55So5Yiw5pyf5ZCO5bCG5YGc5q2i6L+Q6KGM77yM5aaC6ZyA5q2j5byP5o6I5p2D6K+36IGU57O75L2c6ICF44CCIgogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VCb3ggbXNnIHRpdGxlOiLor5XnlKjniYjov5DooYzmj5DnpLoiIGljb246I2luZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWUKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICAgICBsb2NhbCByTGFzdCA9IF9HZXRSZWcgcmVnUGF0aCAiTGFzdFJ1biIKICAgICAgICAgICAgICAgIGlmIHJMYXN0ICE9IHVuZGVmaW5lZCBhbmQgckxhc3QgIT0gIiIgZG8gKAogICAgICAgICAgICAgICAgICAgIHRyeSAoCiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsIGxhc3REdCA9IGR0Q2xhc3MuUGFyc2Ugckxhc3QKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm93IDwgKGxhc3REdC5BZGRNaW51dGVzIC0xMC4wKSBkbyAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbCBtc2cgPSAi4p2MIOOAkOWuieWFqOitpuWRiuOAkSIgKyBfbmwgKyBfbmwgKyAi5qOA5rWL5Yiw6K6h566X5py657O757uf5pe26ZKf5a2Y5Zyo5byC5bi45Zue5ouo77yBIiArIF9ubCArICLor5XnlKjmnJ/pqozor4HlpLHotKXvvIzohJrmnKzlt7Lnu4jmraLov5DooYzjgIIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQm94IG1zZyB0aXRsZToi6K+V55So6aqM6K+B5byC5bi4IiBpY29uOiNjcml0aWNhbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICApIGNhdGNoICgpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICBfU2V0UmVnIHJlZ1BhdGggIkxhc3RSdW4iIG5vd1N0cgoKICAgICAgICAgICAgICAgIGxvY2FsIHN0YXJ0RHQgPSBkdENsYXNzLlBhcnNlIHN0YXJ0U3RyCiAgICAgICAgICAgICAgICBsb2NhbCBzcGFuID0gbm93LlN1YnRyYWN0IHN0YXJ0RHQKICAgICAgICAgICAgICAgIGxvY2FsIGRheXNQYXNzZWQgPSBzcGFuLlRvdGFsRGF5cwogICAgICAgICAgICAgICAgbG9jYWwgcmVtYWluRGF5cyA9IHRvdGFsRGF5cyAtIGRheXNQYXNzZWQKCiAgICAgICAgICAgICAgICBpZiByZW1haW5EYXlzIDw9IDAuMCB0aGVuICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCBtc2cgPSAi4p2MIOOAkOivleeUqOacn+W3sue7k+adn+OAkSIgKyBfbmwgKyBfbmwgKyAi5oKo55qE44CMIiArIHNUaXRsZSArICLjgI0iICsgKHRvdGFsRGF5cyBhcyBzdHJpbmcpICsgIiDlpKnor5XnlKjmnJ/lt7Lnu5PmnZ/vvIEiICsgX25sICsgIuiEmuacrOW3suWBnOatoui/kOihjOOAgiIgKyBfbmwgKyBfbmwgKyAi5aaC6ZyA57un57ut5L2/55So77yM6K+36IGU57O75L2c6ICF6I635Y+W5q2j5byP5ZWG5Lia5o6I5p2D44CCIgogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VCb3ggbXNnIHRpdGxlOiLor5XnlKjlt7LliLDmnJ8iIGljb246I2NyaXRpY2FsCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgICAgICApIGVsc2UgKAogICAgICAgICAgICAgICAgICAgIGxvY2FsIHJlbWFpbkludCA9IChjZWlsIHJlbWFpbkRheXMpIGFzIGludGVnZXIKICAgICAgICAgICAgICAgICAgICBpZiByZW1haW5JbnQgPCAxIGRvIHJlbWFpbkludCA9IDEKICAgICAgICAgICAgICAgICAgICBsb2NhbCBtc2cgPSAi4o+zIOOAkOivleeUqOeJiOi/kOihjOaPkOekuuOAkSIgKyBfbmwgKyBfbmwgKyAi5oKo5q2j5Zyo5L2/55So55qE5piv44CMIiArIHNUaXRsZSArICLjgI3or5XnlKjniYjvvIEiICsgX25sICsgX25sICsgIuKXjyDor5XnlKjmnJ/pmZDvvJoiICsgKHRvdGFsRGF5cyBhcyBzdHJpbmcpICsgIiDlpKkiICsgX25sICsgIuKXjyDliankvZnml7bpl7TvvJrnuqYgIiArIChyZW1haW5JbnQgYXMgc3RyaW5nKSArICIg5aSpIiArIF9ubCArIF9ubCArICLor5XnlKjliLDmnJ/lkI7lsIblgZzmraLov5DooYzvvIzlpoLpnIDmraPlvI/mjojmnYPor7fogZTns7vkvZzogIXjgIIiCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUJveCBtc2cgdGl0bGU6IuivleeUqOeJiOi/kOihjOaPkOekuiIgaWNvbjojaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIGNhdGNoICgKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgICAgICkKICAgICAgICApCiAgICApCiAgICBnbG9iYWwgX21oX3RyaWFsX2F1dGhfcGFzc2VkID0gZmFsc2UKICAgIGxvY2FsIF9taENoZWNrZXIgPSBfTUhUcmlhbENoZWNrZXIoKQogICAgaWYgKF9taENoZWNrZXIuVmVyaWZ5VHJpYWwgIk1heFNjcmlwdOa3t+a3huW3peWFtyIgMyAiNWEyZjM5ZjZhZDA2IikgZG8gKAogICAgICAgIF9taF90cmlhbF9hdXRoX3Bhc3NlZCA9IHRydWUKICAgICkKKQoKaWYgKF9taF9rZXlfYXV0aF9wYXNzZWQgPT0gdHJ1ZSBhbmQgX21oX3RyaWFsX2F1dGhfcGFzc2VkID09IHRydWUpIGRvICgKCnRyeSAoZGVzdHJveURpYWxvZyBGa214MDFjeSApIGNhdGNoICgpCnJvbGxvdXQgRmtteDAxY3kgIuefv+ajieadv+WQiumhtiIgd2lkdGg6MHg4QyBoZWlnaHQ6MHhCQwooCglidXR0b24gYnRuMSAiWyAg5LiAICDplK4gIOeUnyAg5oiQICBdIiBwb3M6WzAsMzVdIHdpZHRoOjE1NSBoZWlnaHQ6MzAgdG9vbFRpcDoi6K+36YCJ5oup5bmz6Z2iIgoJYnV0dG9uIGJ0bjIgIlsgIEwgIEUgIEQgICDnga8gIOadvyAgXSIgcG9zOlswLDcwXSB3aWR0aDoxNTUgaGVpZ2h0OjMwIHRvb2xUaXA6Iuivt+mAieaLqemcgOimgeeUn+aIkOeBr+adv+eahOmdoiIKCWNoZWNrYnV0dG9uIGJ0YyAiWyAg5bu6ICDnu4QgIOW8gCAg5YWzICBdIiBwb3M6WzAsMTA1XSB3aWR0aDoxNTUgaGVpZ2h0OjMwIGVuYWJsZWQ6dHJ1ZSBjaGVja2VkOmZhbHNlCgoJc3Bpbm5lciBzcGYgIumVv+W6piIgcG9zOlsweEEsMHhBXSB3aWR0aDoweDQyIGhlaWdodDoweDEwIHJhbmdlOlswLDEwMDAwLCA0MDBdIHR5cGU6I2ludGVnZXIKCXNwaW5uZXIgc3BoICLlrr3luqYiIHBvczpbMHg1NywweEFdIHdpZHRoOjB4NDIgaGVpZ2h0OjB4MTAgcmFuZ2U6WzAsMTAwMDAsIDQwMF0gdHlwZTojaW50ZWdlcgoKCUltZ1RhZyBJbWdfbWFwIHdpZHRoOjI3MCBoZWlnaHQ6MjAgICBwb3M6Wy01LDE0MF0gYml0bWFwOihiaXRtYXAgMSAxIGNvbG9yOihjb2xvciAxMDAgMTQwIDE4MCkpICBlbmFibGVkOmZhbHNlCiAgICBoeXBlcmxpbmsgbGIxICLkvb/nlKjmlZnnqIsiIHBvczpbMCwxNDNdICBjb2xvcjooY29sb3IgMjUwIDI1MCAyNTApICAgY29sb3I6KGNvbG9yIDI1MCAyNTAgMjUwKSAgYWRkcmVzczoiaHR0cDovL3d3dy5ma214ZHMuY24vaHRtbC8yMDE5L2ptXzA2MjAvMjUzLmh0bWwiICBob3ZlcmNvbG9yOihjb2xvciAyNTAgMjUwIDI1MCkKCglmbiBGaXhUcmFuc2Zvcm1CeUZhY2UgZmFjZSA9CgkoCgkJCWlmIGNsYXNzb2YgZmFjZSA9PSBFZGl0YWJsZV9tZXNoIHRoZW4gKG5mID0gdHJ5KGdldEZhY2VOb3JtYWwgZmFjZSAoZ2V0RmFjZVNlbGVjdGlvbiAkIGFzIGFycmF5KVsxXSljYXRjaChnZXRGYWNlTm9ybWFsIGZhY2UgMSkpCgkJCWlmIGNsYXNzb2YgZmFjZSA9PSBFZGl0YWJsZV9Qb2x5IHRoZW4gKG5mID0gdHJ5KHBvbHlvcC5nZXRGYWNlTm9ybWFsIGZhY2UgKHBvbHlvcC5nZXRGYWNlU2VsZWN0aW9uIGZhY2UgYXMgYXJyYXkpWzFdKWNhdGNoKHBvbHlvcC5nZXRGYWNlTm9ybWFsIGZhY2UgMSkpCgkJCWZjPWZhY2UucG9zCgkJCXh2ID0gbm9ybWFsaXplIChjcm9zcyBuZiBbMCwwLDFdKQoJCQl5diA9IG5vcm1hbGl6ZSAoY3Jvc3MgbmYgeHYpCgkJCWFjPVswLDAsMF0KCgkJCWZhY2UudHJhbnNmb3JtKj1pbnZlcnNlIChtYXRyaXgzIHh2IHl2IG5mIGFjKQoJCQlSZXNldFhGb3JtIGZhY2UKCQkJY29sbGFwc2VzdGFjayBmYWNlCgkJCWZhY2UudHJhbnNmb3JtPShtYXRyaXgzIHh2IHl2IG5mIGFjKQoJCQlmYWNlLnBvcz1mYwoJKQoKCW9uIEZrbXgwMWN5IG9wZW4gIGRvCgkoCgl0cnkKCSgKICAgICBDa291VHViaWFvIEZrbXgwMWN5CgkpCgljYXRjaChtZXNzYWdlQm94ICLmk43kvZzplJnor68iKQogICAgKQoKCWxvY2FsIGJhc2UgPSB1bmRlZmluZWQKCglsb2NhbCBmbG9vclNwYWNlID0gdW5kZWZpbmVkCglsb2NhbCBwX1dpZHRoID0gIDMwMC4wCgoJbG9jYWwgcF9XaWR0aFIJPSAzMDAuMAoKCWxvY2FsIHBfTGVuZ3RoID0zMDAuMAoJbG9jYWwgcF9MZW5ndGhSID0zMDAuMAoKCWxvY2FsIHBfR2FwTGVuZ3RoPSAwLjAKCglsb2NhbCBwYXRXaWR0aCA9IHVuZGVmaW5lZAoKCWxvY2FsIHBfUm93T2Zmc2V0ID0yMC4wCgoJbG9jYWwgcF9PZmZzZXRMZW5ndGggPTAuMAoKCWxvY2FsIHBfT2Zmc2V0V2lkdGggPTAuMAoKCWxvY2FsIHBhdExlbmd0aCA9IHVuZGVmaW5lZAoJbG9jYWwgcGF0T3JpZ2luID0gdW5kZWZpbmVkCgoJbG9jYWwgZmxvb3JPYmplY3QgPSB1bmRlZmluZWQKCglsb2NhbCBmbG9vck9iamVjdE9sZCA9IHVuZGVmaW5lZAoKCWxvY2FsIG9iak9sZCA9IHVuZGVmaW5lZAoKCWxvY2FsIG9sZE1vZGlmaWVycyA9ICMoKQoKCWxvY2FsIHpPZmZzZXQgPSB1bmRlZmluZWQKCglmbiBldmFsdWF0ZVBhcmFtZXRlcnMgPSAoCgoJCXBfV2lkdGggPSAgc3BoLnZhbHVlCgoJCXBfV2lkdGhSCT0gc3BoLnZhbHVlCgoJCXBfTGVuZ3RoID0gc3BmLnZhbHVlCgkJcF9MZW5ndGhSID1zcGYudmFsdWUKCQlwX1Jvd09mZnNldCA9MjAKCgkJcF9PZmZzZXRMZW5ndGggPTAuMAoKCQlwX09mZnNldFdpZHRoID0wLjAKCgkpCgoJZm4gcm5kID0gKCByYW5kb20gLjAgMS4JKQoKCWZuIHVybmQgPSAoIHJhbmRvbSAtMS4gMS4gKQoKCWZuIGZsaXBDb2luID0gKCByYW5kb20gMCAxID09IDAgKQoKCWZuIG1heEFuZ2xlIHcgbCBnID0gKAoJbG9jYWwgeCA9IHNxcnQgKHcqdyAqIC4yNSArIGwqbCAqIC4yNSkKCWxvY2FsIG0gPSAodyArIGcpICogLjUKCWlmIHggPCBtIHRoZW4KCQlyZXR1cm4gMTgwLjAKCWxvY2FsIGEgPSBhdGFuICh3IC8gbCkKCWxvY2FsIGIgPSBhY29zIChtIC8geCkKCTkwLjAgLSBhIC0gYgoJKQoJZm4gc3ByZWFkQ3VydmUgc3ByZWFkIHZhbCA9ICgKCQlpZiBzcHJlYWQgPCAwLjAwMDAxIHRoZW4gcmV0dXJuIDAuCgkJaWYgc3ByZWFkID4gMC45OTk5OSB0aGVuIHJldHVybiAxLgoJCWlmIHZhbCA8IDEuIC0gc3ByZWFkIHRoZW4KCQkJcmV0dXJuICgoc3ByZWFkIC8gKDEuIC0gc3ByZWFkKSkgKiB2YWwpCgkJZWxzZQoJCQlyZXR1cm4gKCgxLiAtIHNwcmVhZCkgKiAodmFsIC0gMS4pIC8gc3ByZWFkICsgMS4pCgkpCgoJZm4gcmFuZCBmcm9tVmFsIHRvVmFsIHNwcmVhZCA9ICgKCQlmcm9tVmFsICsgKHRvVmFsIC0gZnJvbVZhbCkgKiAoc3ByZWFkQ3VydmUgKHJuZCgpKSBzcHJlYWQpCgkpCgoJZm4gaW5pdE5vZGVzIHRvTm9kZSBvbGRGbG9vcjp1bmRlZmluZWQgPSAoCgoJCWlmIG9sZEZsb29yICE9IHVuZGVmaW5lZCB0aGVuICgKCQkJZmxvb3JPYmplY3QgPSBvbGRGbG9vcgoKCQkJb2xkTW9kaWZpZXJzID0gIygpCgkJCWZvciBpIGluIDEgdG8gZmxvb3JPYmplY3QubW9kaWZpZXJzLmNvdW50IGRvCgkJCQlvbGRNb2RpZmllcnNbaV0gPSBmbG9vck9iamVjdC5tb2RpZmllcnNbaV0KCgkJCXdoaWxlIGZsb29yT2JqZWN0Lm1vZGlmaWVycy5jb3VudCA+IDAgZG8KCQkJCWRlbGV0ZU1vZGlmaWVyIGZsb29yT2JqZWN0IDEKCgkJCXNldE1lc2ggZmxvb3JPYmplY3QgbnVtdmVydHM6MCBudW1mYWNlczowCgkJCXVwZGF0ZSBmbG9vck9iamVjdAoJCQlmbG9vck9iamVjdC50cmFuc2Zvcm0gPSBtYXRyaXgzIDEKCQkpIGVsc2UgKAoJCQlmbG9vck9iamVjdCA9IGVkaXRhYmxlX21lc2ggbmFtZToodW5pcXVlbmFtZSAi55+/5qOJ5p2/X1NlYV9OX09iamVjdCIpCgkJKQoKCQliYXNlID0gZWRpdGFibGVfbWVzaCBuYW1lOih1bmlxdWVuYW1lICLnn7/mo4nmnb9fU2VhX05fVGVtcG9yYXJ5T2JqZWN0IikKCQlhdHRhY2ggYmFzZSAoY29weSB0b05vZGUpCgoJCXpPZmZzZXQgPSAwLjAKCQlsb2NhbCB4eVBvaW50CgkJZm9yIGkgaW4gMSB0byBnZXROdW1WZXJ0cyBiYXNlIGRvICgKCQkJeHlQb2ludCA9IGdldFZlcnQgYmFzZSBpCgkJCXpPZmZzZXQgKz0geHlQb2ludC56CgkJCXh5UG9pbnQueiA9IDAuMAoJCQlzZXRWZXJ0IGJhc2UgaSB4eVBvaW50CgkJKQoJCXpPZmZzZXQgLz0gZ2V0TnVtVmVydHMgYmFzZQoJKQoKCWZuIGNyZWF0ZU1hdHJpeDMgcCA9ICgKCQlsb2NhbCB4ID0gWzEsMCwwXQoJCWxvY2FsIHkgPSBbMCwxLDBdCgkJbG9jYWwgeiA9IFswLDAsMV0KCQlmbG9vclJvdGF0aW9uID0gcXVhdCAoMCkgegoJCXggKj0gZmxvb3JSb3RhdGlvbgoJCXkgKj0gZmxvb3JSb3RhdGlvbgoJCWZsb29yU3BhY2UgPSBNYXRyaXgzIHggeSB6IHAKCSkKCglmbiBjYWxjQm91bmRpbmdCb3ggPSAoCgkJYmIxID0gKGdldFZlcnQgYmFzZSAxKSAqIChpbnZlcnNlIGZsb29yU3BhY2UpCgkJYmIyID0gKGdldFZlcnQgYmFzZSAxKSAqIChpbnZlcnNlIGZsb29yU3BhY2UpCgoJCWxvY2FsIG51bSA9IGdldE51bVZlcnRzIGJhc2UKCQlsb2NhbCB2CgkJZm9yIGkgaW4gMSB0byBudW0gZG8gKAoJCQl2ID0gZ2V0VmVydCBiYXNlIGkKCQkJdiAqPSAoaW52ZXJzZSBmbG9vclNwYWNlKQoJCQlpZiBiYjEueCA8IHYueCB0aGVuIGJiMS54ID0gdi54CgkJCWVsc2UgaWYgYmIyLnggPiB2LnggdGhlbiBiYjIueCA9IHYueAoJCQlpZiBiYjEueSA+IHYueSB0aGVuIGJiMS55ID0gdi55CgkJCWVsc2UgaWYgYmIyLnkgPCB2LnkgdGhlbiBiYjIueSA9IHYueQoJCSkKCQliYjEueiA9IGJiMi56ID0gMAoJCXBhdE9yaWdpbiA9IFtiYjIueCwgYmIxLnksIDBdCgkJcGF0V2lkdGggPSBiYjIueSAtIGJiMS55CgkJcGF0TGVuZ3RoID0gYmIxLnggLSBiYjIueAoJKQoJZm4gY3JlYXRlUG9seWdvbiBwMSBwMiBpZCA9ICgKCQlsb2NhbCBudW0gPSBnZXROdW1WZXJ0cyBmbG9vck9iamVjdCArIDEKCQlzZXROdW1WZXJ0cyBmbG9vck9iamVjdCAobnVtICsgMykgdHJ1ZQoJCXNldFZlcnQgZmxvb3JPYmplY3QgKG51bSAgKSBbcDEueCxwMi55LDBdCgkJc2V0VmVydCBmbG9vck9iamVjdCAobnVtKzEpIHAyCgkJc2V0VmVydCBmbG9vck9iamVjdCAobnVtKzIpIFtwMi54LHAxLnksMF0KCQlzZXRWZXJ0IGZsb29yT2JqZWN0IChudW0rMykgcDEKCQltZXNob3AuY3JlYXRlUG9seWdvbiBmbG9vck9iamVjdCAjKG51bSwgbnVtKzEsIG51bSsyLCBudW0rMykgbWF0SUQ6aWQKCgkpCgoJZm4gY3JlYXRlUGF0dGVybl8wMSA9ICgKCQlwbGFua1BvcyA9ICMoKQoJCXBsYW5rUm90ID0gIygpCgkJcGxhbmtUaWx0ID0gIygpCgkJcGxhbmtMZW5NaW4gPSAjKCkKCQlwbGFua0xlbk1heCA9ICMoKQoKCQlsb2NhbCB0b3RhbFdpZHRoID0gLShwX1dpZHRoKQoKCQlsb2NhbCB4LHkseix3LHAxLHAyLHAzLHA0LGNlbnRlcixyb3QscSxtaW5MLG1heEwscFgscFksclgsclkscixtYXhBLG1heEIsdXZSYW5kCgkJbG9jYWwgcm93ID0gMAoJCWxvY2FsIGNvdW50ID0gMQoJCWxvY2FsIGxlbmd0aFBsdXNHYXAgPSBwX0xlbmd0aAoJCXdoaWxlIHRvdGFsV2lkdGggPCAocGF0V2lkdGggKyBwX1dpZHRoICkgZG8KCQkoCgoJCQl4ID0gcF9XaWR0aAoKCQkJeSA9IDAuMAoJCQl0b3RhbExlbmd0aCA9IG1vZCAoLShsZW5ndGhQbHVzR2FwKSAqIHBfUm93T2Zmc2V0ICogcm93KSBsZW5ndGhQbHVzR2FwCgkJCXRvdGFsTGVuZ3RoICs9IC1sZW5ndGhQbHVzR2FwCgoJCQl3aGlsZSB0b3RhbExlbmd0aCA8IChwYXRMZW5ndGggKyBsZW5ndGhQbHVzR2FwKSBkbyAoCgoJCQkJeiA9IHJhbmQgcF9MZW5ndGhSIHBfTGVuZ3RoICgwLjUpCgkJCQl3ID0gcF9HYXBMZW5ndGgKCgkJCQlyWCA9IDAKCgkJCQlyWSA9IDAKCgkJCQlpZiBmbGlwQ29pbigpIHRoZW4gclggPSAtclgKCQkJCWlmIGZsaXBDb2luKCkgdGhlbiByWSA9IC1yWQoJCQkJcFggPSB0b3RhbExlbmd0aCAtIHJYCgkJCQlwWSA9IHRvdGFsV2lkdGggLSByWQoKCQkJCXAxID0gW3BYLCAgIHBZK3gsIDBdICsgcGF0T3JpZ2luCgkJCQlwMiA9IFtwWCt6LCBwWSwgICAwXSArIHBhdE9yaWdpbgoJCQkJcDMgPSBbcDEueCxwMi55LDBdCgkJCQlwNCA9IFtwMi54LHAxLnksMF0KCgkJCQljcmVhdGVQb2x5Z29uIHAxIHAyIGNvdW50CgoJCQkJY2VudGVyID0gWyhwWCt6LzIuKSwgKHBZK3gvMi4pLCAwXSArIHBhdE9yaWdpbgoJCQkJcGxhbmtQb3NbY291bnRdID0gY2VudGVyCgoJCQkJY291bnQgKz0gMQoJCQkJdG90YWxMZW5ndGggKz0geiArIHcKCQkJKQoKCQkJcm93ICs9IDEKCQkJdG90YWxXaWR0aCArPSB4ICsgeQoJCSkKCSkKCWZuIGNyZWF0ZUZsb29yIG9iaiB4eG9iaiBvbGRGbG9vcjp1bmRlZmluZWQgPSAoCgoJKAoKCQlsb2NhbCBwID0gb2JqLnBvcwoJCWV2YWx1YXRlUGFyYW1ldGVycygpCgkJY3JlYXRlTWF0cml4MyBwCgoJCWluaXROb2RlcyBvYmogb2xkRmxvb3I6b2xkRmxvb3IKCQljYWxjQm91bmRpbmdCb3goKQoJCWNyZWF0ZVBhdHRlcm5fMDEoKQoKCQlmbG9vck9iamVjdC5wb3MgPSBbcC54LCBwLnksIDAuMF0KCQlhZGRNb2RpZmllciBiYXNlIChTaGVsbCBpbm5lckFtb3VudDoxLiBvdXRlckFtb3VudDoxLikKCQlmbG9vck9iamVjdCAqIGJhc2UKCgkJbG9jYWwgYWxsID0gI3t9CgkJYWxsLmNvdW50ID0gZ2V0TnVtVmVydHMgZmxvb3JPYmplY3QKCQlhbGwgPSAtYWxsCgoJCW1lc2hvcC53ZWxkVmVydHNCeVRocmVzaG9sZCBmbG9vck9iamVjdCBhbGwgMC4xCgoJCWRlbGV0ZSBiYXNlCgkJcGxhbmtQb3MgPSAjKCkKCQlwbGFua1JvdCA9ICMoKQoJCXBsYW5rVGlsdCA9ICMoKQoJCXBsYW5rVGlsdFN0ciA9ICMoKQoJCXBsYW5rTGVuTWluID0gIygpCgkJcGxhbmtMZW5NYXggPSAjKCkKCgkJZW5hYmxlU2NlbmVSZWRyYXcoKQoKCQlmbG9vck9iamVjdE9sZCA9IGZsb29yT2JqZWN0CgkJb2JqT2xkID0geHhvYmoKCQkpCgkJZmxvb3JPYmplY3RPbGQKCgkpCgoJb24gYnRuMSBwcmVzc2VkIGRvCgkoCgkJCSgKCXRyeQooCgkJCW1heCBjcmVhdGUgbW9kZQoJCQlpc3BvbHkgPSBmYWxzZQoJCQlOZXdPYmogPSAiIgoJCQlvYmogPSBmb3IgaSBpbiBzZWxlY3Rpb24gY29sbGVjdCBpCgkJCWlmIG9iai5jb3VudCA9PSAxIGFuZCBzdWJvYmplY3RMZXZlbCA9PSA0IGFuZCBjbGFzc29mIG9ialsxXSA9PSBFZGl0YWJsZV9Qb2x5IHRoZW4KCQkJKAoJCQkJc2VsZmFjZSA9IHBvbHlvcC5nZXRGYWNlU2VsZWN0aW9uIG9ialsxXSBhcyBhcnJheQoJCQkJaWYgc2VsZmFjZS5jb3VudCA9PSAxIHRoZW4KCQkJCSgKCQkJCQluZXdOYW1lID0gdW5pcXVlbmFtZSBvYmpbMV0ubmFtZQoJCQkJCXBvbHlPcC5kZXRhY2hGYWNlcyBvYmpbMV0gI3tzZWxmYWNlWzFdfSBhc05vZGU6dHJ1ZSBkZWxldGU6ZmFsc2UgbmFtZTpuZXdOYW1lCgkJCQkJTmV3T2JqID0gZ2V0bm9kZWJ5bmFtZSBuZXdOYW1lCgkJCQkJaXNwb2x5ID0gdHJ1ZQoJCQkJKQoJCQkpCgkJCWlmIGlzcG9seSB0aGVuIChvYmoyID0gTmV3T2JqKSBlbHNlIChvYmoyID0gY29weSBvYmpbMV0pCgkJCWlmIGNsYXNzb2Ygb2JqMiAhPSBFZGl0YWJsZV9Qb2x5IHRoZW4KCQkJKAoKCQkJCWNvbnZlcnRUbyBvYmoyIEVkaXRhYmxlX1BvbHkKCgkJCSkKCgkJCUZpeFRyYW5zZm9ybUJ5RmFjZSBvYmoyCgkJCUNlbnRlclBpdm90IG9iajIKCQkJY2MgPSBjb3B5IG9iajIKCQkJY2MudHJhbnNmb3JtID0gKG1hdHJpeDMgWzEsMCwwXSBbMCwxLDBdIFswLDAsMV0gWzAsMCwwXSkKCgkJCW5ld29iaiA9IGNyZWF0ZUZsb29yIGNjIG9ialsxXQoKCQkJV29ybGRBbGlnblBpdm90IG5ld29iagoJCQlDZW50ZXJQaXZvdCBuZXdvYmoKCQkJbmV3b2JqLnBpdm90ID0gY2MucGl2b3QKCQkJbmV3b2JqLnRyYW5zZm9ybSA9IG9iajIudHJhbnNmb3JtCgkJCWNvbnZlcnRUbyBuZXdvYmogRWRpdGFibGVfUG9seQoJCQlkZWxldGUgb2JqMjtkZWxldGUgY2MKCQkJc2VsZWN0IG5ld29iagoKCQkJaWYgIHNlbGVjdGlvbiAuY291bnQgPT0gMSB0aGVuCgkJCSgKCgkJCQltYXggbW9kaWZ5IG1vZGUKCQkJCW1hY3JvcyAucnVuICJNb2RpZmllciBTdGFjayIgIkNvbnZlcnRfdG9fUG9seSIKCQkJCXN1Ym9iamVjdExldmVsID0gMwoJCQkJbWF4IHNlbGVjdCBhbGwKCQkJCXN1Ym9iamVjdExldmVsID0gMgoJCQkJbWF4IHNlbGVjdCBpbnZlcnQKCQkJCUEgPSBuZXdvYmouRWRpdGFibGVQb2x5IC5HZXRTZWxlY3Rpb24gI0VkZ2UKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLkNvbnZlcnRTZWxlY3Rpb24gI0VkZ2UgI0ZhY2UKCQkJCXN1Ym9iamVjdExldmVsID0gNAoJCQkJbmV3b2JqLmluc2V0VHlwZSA9IDEKCQkJCW5ld29iai5pbnNldEFtb3VudCA9IDgKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLmJ1dHRvbk9wICNJbnNldAoJCQkJRCA9IG5ld29iai5FZGl0YWJsZVBvbHkgLkdldFNlbGVjdGlvbiAjZmFjZQoJCQkJbmV3b2JqLkVkaXRhYmxlUG9seSAuQ29udmVydFNlbGVjdGlvbiAjRmFjZSAjRWRnZQoJCQkJc3Vib2JqZWN0TGV2ZWwgPSAweDIKCQkJCUIgPSBuZXdvYmouRWRpdGFibGVQb2x5IC5HZXRTZWxlY3Rpb24gI0VkZ2UKCQkJCXN1Ym9iamVjdExldmVsID0gMHg0CgkJCQluZXdvYmouZmFjZUV4dHJ1ZGVIZWlnaHQgPSAweDMKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLmJ1dHRvbk9wICNFeHRydWRlCgkJCQlDID0gbmV3b2JqLkVkaXRhYmxlUG9seSAuR2V0U2VsZWN0aW9uICNmYWNlCgkJCQlzdWJvYmplY3RMZXZlbCA9IDB4MgoJCQkJbmV3b2JqLmVkZ2VDaGFtZmVyID0gMHgyCgkJCQluZXdvYmouZWRnZUNoYW1mZXJTZWdtZW50cyA9IDB4MgoJCQkJbmV3b2JqLkVkaXRhYmxlUG9seSAuYnV0dG9uT3AgI0NoYW1mZXIKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLlNldFNlbGVjdGlvbiAjRWRnZSAoQSApCgkJCQluZXdvYmouZWRnZUV4dHJ1ZGVXaWR0aCA9IDEuNzU2MzUKCQkJCW5ld29iai5lZGdlRXh0cnVkZUhlaWdodCA9IDAuNjYKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLmJ1dHRvbk9wICNFeHRydWRlCgkJCQluZXdvYmouRWRpdGFibGVQb2x5IC5Db252ZXJ0U2VsZWN0aW9uICNFZGdlICNGYWNlCgkJCQlzdWJvYmplY3RMZXZlbCA9IDB4NAoJCQkJRiA9IG5ld29iai5FZGl0YWJsZVBvbHkgLkdldFNlbGVjdGlvbiAjZmFjZQoJCQkJbmV3b2JqLkVkaXRhYmxlUG9seSAuU2V0U2VsZWN0aW9uICNmYWNlIChDICkKCQkJCW5ld05hbWUgPSB1bmlxdWVuYW1lICLnn7/mo4nmnb9fU2VhX05fIgoJCQkJcG9seU9wIC5kZXRhY2hGYWNlcyBuZXdvYmogbmV3b2JqLnNlbGVjdGVkZmFjZXMgYXNOb2RlOm9uIGRlbGV0ZTpvbiBuYW1lOm5ld05hbWUKCQkJCVRlbXBfS3VhbmdNaWFuQmFuID0gZ2V0bm9kZWJ5bmFtZSBuZXdOYW1lCgkJCQluZXdvYmouRWRpdGFibGVQb2x5IC5TZXRTZWxlY3Rpb24gI2ZhY2UgKEYgKQoJCQkJbWFjcm9zIC5ydW4gIlBvbHlUb29scyIgInNpbWlsYXIiCgkJCQluZXdOYW1lMiA9IHVuaXF1ZW5hbWUgIuefv+ajieadv1/pu5HmnaFfU2VhX05fIgoJCQkJcG9seU9wIC5kZXRhY2hGYWNlcyBuZXdvYmogbmV3b2JqLnNlbGVjdGVkZmFjZXMgYXNOb2RlOm9uIGRlbGV0ZTpvbiBuYW1lOm5ld05hbWUyCgkJCQlUZW1wX0t1YW5nTWlhbkJhbl9IZWlUaWFvID0gZ2V0bm9kZWJ5bmFtZSBuZXdOYW1lMgoJCQkJc3Vib2JqZWN0TGV2ZWwgPSAweDAKCQkJCW5ld29iai5OYW1lPXVuaXF1ZW5hbWUgIuefv+ajieadv1/pvpnpqqhfU2VhX05fIgoKCQkJCU1hdF9IZWlUaWFvID0gU3RhbmRhcmRtYXRlcmlhbCAoKQoJCQkJTWF0X0hlaVRpYW8uRGlmZnVzZSA9IGNvbG9yIDB4RiAweEYgMHhGCgkJCQlUZW1wX0t1YW5nTWlhbkJhbl9IZWlUaWFvLm1hdGVyaWFsID0gTWF0X0hlaVRpYW8KCQkJCU1hdF9Mb25nR3UgPSBTdGFuZGFyZG1hdGVyaWFsICgpCgkJCQlNYXRfTG9uZ0d1LkRpZmZ1c2UgPSBjb2xvciAweDUyIDB4NTYgMHg1OQoKCQkJCW5ld29iai5tYXRlcmlhbCA9IE1hdF9Mb25nR3UKCQkJCU1hdF9iYW4gPSBTdGFuZGFyZG1hdGVyaWFsICgpCgkJCQlNYXRfYmFuLkRpZmZ1c2UgPSBjb2xvciAweEZGIDB4RkYgMHhGRgoJCQkJVGVtcF9LdWFuZ01pYW5CYW4ubWF0ZXJpYWwgPSBNYXRfYmFuCgkJCQlzZWxlY3QgIyhuZXdvYmosIFRlbXBfS3VhbmdNaWFuQmFuLCBUZW1wX0t1YW5nTWlhbkJhbl9IZWlUaWFvKQoJCQkJZ3JvdXAgJAoKCQkJKQoJCSkKCWNhdGNoKG1lc3NhZ2VCb3ggIuaTjeS9nOmUmeivryIpCiAgICApCgoJKQoJb24gYnRuMiBwcmVzc2VkIGRvCgkoCgkJaWYgc3Vib2JqZWN0TGV2ZWwgPT0gMHg0IHRoZW4KCQkoCgkJCXBvbHlPcCAuZGV0YWNoRmFjZXMgJCAkLnNlbGVjdGVkZmFjZXMgYXNOb2RlOm9uIGRlbGV0ZTpvbiBuYW1lOiJMRUREZW5nIgoJCQltZWRpdE1hdGVyaWFscyBbMHgxXSA9IFN0YW5kYXJkICgpCgkJCW1lZGl0TWF0ZXJpYWxzIFsweDFdLnNlbGZJbGx1bUNvbG9yID0gY29sb3IgMHhGRiAweEZGIDB4RkYKCQkJbWVkaXRNYXRlcmlhbHMgWzB4MV0udHdvU2lkZWQgPSBvbgoJCQltZWRpdE1hdGVyaWFscyBbMHgxXS51c2VTZWxmSWxsdW1Db2xvciA9IG9uCgkJCSRMRUREZW5nKi5tYXRlcmlhbCA9IG1lZGl0TWF0ZXJpYWxzIFsweDFdCgkJKQoJKQoJb24gYnRjIGNoYW5nZWQgc3RhdGUgZG8KCSgKCQlpZiBzZWxlY3Rpb24gLmNvdW50ID4gMHgwIHRoZW4KCQkoCgkJCWlmIGJ0YyAuY2hlY2tlZCA9PSB0cnVlIHRoZW4KCQkJKAoJCQkJYnRjIC50ZXh0ID0gIuW3suaJk+W8gCIKCQkJCXRyeSAoZm9yIGEgaW4gc2VsZWN0aW9uIGRvIGlmIGlzZ3JvdXBoZWFkIGEgdGhlbiBzZXRncm91cG9wZW4gYSB0cnVlICljYXRjaCAoKQoJCQkJdHJ5IChvayApY2F0Y2ggKCkKCQkJKQoJCQllbHNlIGlmIGJ0YyAuY2hlY2tlZCA9PSBmYWxzZSB0aGVuCgkJCSgKCQkJCWJ0YyAudGV4dCA9ICLlt7LlhbPpl60iCgkJCQl0cnkgKGZvciBhIGluIG9iamVjdHMgZG8gaWYgaXNncm91cGhlYWQgYSB0aGVuIHNldGdyb3Vwb3BlbiBhIGZhbHNlICljYXRjaCAoKQoJCQkJdHJ5IChvayApY2F0Y2ggKCkKCQkJKQoJCSkKCQllbHNlIG1lc3NhZ2Vib3ggIuivt+mAieaLqeW8gOe7hOeJqeS9kyIKCSkKKQpjcmVhdGVEaWFsb2cgRmtteDAxY3kgIDE1NSAxNjUgMjIyIDIwMApjbGVhckxpc3RlbmVyICgpCik="
if _mxs_code != undefined and _mxs_code.count > 0 do (
execute _mxs_code
)
)
High混淆方式:
-- [MaxScript Shield] High Advanced Obfuscation
(
global _jk_c3a92e = 4003 * (random 1 10)
local _jk_3a6b90 = 646
struct _st_60bf18 (
private
fn _dc_9bb7b5 _0xStr = (
try (
local _bytes = (dotNetClass "System.Convert").FromBase64String _0xStr
(dotNetClass "System.Text.Encoding").UTF8.GetString _bytes
) catch ( "" )
),
public
fn _ex_171884 = (
local _code = _dc_9bb7b5 "KAogICAgc3RydWN0IF9NSEtleUd1YXJkICgKICAgICAgICBwcml2YXRlCiAgICAgICAgZm4gX0dldFJlZyBrIHZOYW1lID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLk9wZW5TdWJLZXkgayBmYWxzZQogICAgICAgICAgICAgICAgaWYgc2sgIT0gdW5kZWZpbmVkIGRvICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCB2ID0gc2suR2V0VmFsdWUgdk5hbWUKICAgICAgICAgICAgICAgICAgICBzay5DbG9zZSgpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2IGFzIHN0cmluZykKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkCiAgICAgICAgKSwKICAgICAgICBmbiBfU2V0UmVnIGsgdk5hbWUgdmFsID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLkNyZWF0ZVN1YktleSBrCiAgICAgICAgICAgICAgICBpZiBzayAhPSB1bmRlZmluZWQgZG8gKAogICAgICAgICAgICAgICAgICAgIHNrLlNldFZhbHVlIHZOYW1lICh2YWwgYXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHNrLkNsb3NlKCkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICksCiAgICAgICAgZm4gX0NvbXB1dGVIYXNoIHMgPSAoCiAgICAgICAgICAgIHRyeSAoCiAgICAgICAgICAgICAgICBsb2NhbCBzaGEgPSAoZG90TmV0Q2xhc3MgIlN5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHkuU0hBMjU2IikuQ3JlYXRlKCkKICAgICAgICAgICAgICAgIGxvY2FsIGJ5dGVzID0gKGRvdE5ldENsYXNzICJTeXN0ZW0uVGV4dC5FbmNvZGluZyIpLlVURjguR2V0Qnl0ZXMgKHMgYXMgc3RyaW5nKQogICAgICAgICAgICAgICAgbG9jYWwgaGFzaCA9IHNoYS5Db21wdXRlSGFzaCBieXRlcwogICAgICAgICAgICAgICAgbG9jYWwgaGV4ID0gKGRvdE5ldENsYXNzICJTeXN0ZW0uQml0Q29udmVydGVyIikuVG9TdHJpbmcgaGFzaAogICAgICAgICAgICAgICAgcmV0dXJuICh0b0xvd2VyIChzdWJzdGl0dXRlU3RyaW5nIGhleCAiLSIgIiIpKQogICAgICAgICAgICApIGNhdGNoICggcmV0dXJuICIiICkKICAgICAgICApLAogICAgICAgIHB1YmxpYwogICAgICAgIGZuIFZlcmlmeUtleSBzVGl0bGUgZXhwZWN0ZWRIYXNoIHNJZCA9ICgKICAgICAgICAgICAgZ2xvYmFsIF9taF90YXJnZXRfdGl0bGUgPSAoc1RpdGxlIGFzIHN0cmluZykKICAgICAgICAgICAgZ2xvYmFsIF9taF9pbnB1dF9yZXMgPSBmYWxzZQogICAgICAgICAgICBnbG9iYWwgX21oX2lucHV0X2tleSA9ICIiCiAgICAgICAgICAgIHJvbGxvdXQgX01IS2V5SW5wdXRSb2xsICLmj5Lku7bmjojmnYPlr4bpkqXpqozor4EiIHdpZHRoOjM0MCBoZWlnaHQ6MTU1ICgKICAgICAgICAgICAgICAgIGxhYmVsIGxibDEgIiIgcG9zOlsyMCwxOF0gd2lkdGg6MzAwIGhlaWdodDoyMAogICAgICAgICAgICAgICAgZWRpdHRleHQgZWR0S2V5ICIiIHBvczpbMTUsNDhdIHdpZHRoOjMwMCBoZWlnaHQ6MjYKICAgICAgICAgICAgICAgIGJ1dHRvbiBidG5PSyAi6aqM6K+B5bm25r+A5rS7IiBwb3M6WzMwLDk1XSB3aWR0aDoxMzAgaGVpZ2h0OjM1CiAgICAgICAgICAgICAgICBidXR0b24gYnRuQ2FuY2VsICLlj5bmtojpgIDlh7oiIHBvczpbMTgwLDk1XSB3aWR0aDoxMzAgaGVpZ2h0OjM1CgogICAgICAgICAgICAgICAgb24gX01IS2V5SW5wdXRSb2xsIG9wZW4gZG8gKAogICAgICAgICAgICAgICAgICAgIGxibDEudGV4dCA9ICLor7fovpPlhaXjgIwiICsgKF9taF90YXJnZXRfdGl0bGUgYXMgc3RyaW5nKSArICLjgI3nmoTmjojmnYPov5DooYzlr4bpkqXvvJoiCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICAgICAgb24gYnRuT0sgcHJlc3NlZCBkbyAoCiAgICAgICAgICAgICAgICAgICAgbG9jYWwgayA9IGVkdEtleS50ZXh0CiAgICAgICAgICAgICAgICAgICAgaWYgayAhPSB1bmRlZmluZWQgYW5kICh0cmltUmlnaHQgKHRyaW1MZWZ0IGspKS5jb3VudCA+IDAgdGhlbiAoCiAgICAgICAgICAgICAgICAgICAgICAgIF9taF9pbnB1dF9rZXkgPSB0cmltUmlnaHQgKHRyaW1MZWZ0IGspCiAgICAgICAgICAgICAgICAgICAgICAgIF9taF9pbnB1dF9yZXMgPSB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc3Ryb3lEaWFsb2cgX01IS2V5SW5wdXRSb2xsCiAgICAgICAgICAgICAgICAgICAgKSBlbHNlICgKICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUJveCAi6K+36L6T5YWl5pyJ5pWI55qE6L+Q6KGM5a+G6ZKl77yBIiB0aXRsZToi5o+Q56S6IiBpY29uOiN3YXJuaW5nCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgb24gYnRuQ2FuY2VsIHByZXNzZWQgZG8gKAogICAgICAgICAgICAgICAgICAgIF9taF9pbnB1dF9yZXMgPSBmYWxzZQogICAgICAgICAgICAgICAgICAgIGRlc3Ryb3lEaWFsb2cgX01IS2V5SW5wdXRSb2xsCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKICAgICAgICAgICAgY3JlYXRlRGlhbG9nIF9NSEtleUlucHV0Um9sbCBtb2RhbDp0cnVlIHN0eWxlOiMoI3N0eWxlX3RpdGxlYmFyLCAjc3R5bGVfYm9yZGVyLCAjc3R5bGVfc3lzbWVudSkKCiAgICAgICAgICAgIGxvY2FsIF9ubCA9IChkb3ROZXRDbGFzcyAiU3lzdGVtLkVudmlyb25tZW50IikuTmV3TGluZQogICAgICAgICAgICBpZiBfbWhfaW5wdXRfcmVzID09IHRydWUgZG8gKAogICAgICAgICAgICAgICAgaWYgKF9Db21wdXRlSGFzaCBfbWhfaW5wdXRfa2V5KSA9PSBleHBlY3RlZEhhc2ggdGhlbiAoCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUJveCAoIvCfjokg44CQ5o6I5p2D5oiQ5Yqf44CRIiArIF9ubCArIF9ubCArICLlr4bpkqXpqozor4HpgJrov4fvvIzmrKLov47kvb/nlKjvvIEiKSB0aXRsZToi5o6I5p2D5oiQ5YqfIiBpY29uOiNpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgICAgICAgICApIGVsc2UgKAogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VCb3ggKCLinYwg44CQ5a+G6ZKl6ZSZ6K+v44CRIiArIF9ubCArIF9ubCArICLmgqjovpPlhaXnmoTmjojmnYPov5DooYzlr4bpkqXkuI3mraPnoa7vvIzor7fogZTns7vkvZzogIXojrflj5bmraPnoa7lr4bpkqXvvIEiKSB0aXRsZToi5o6I5p2D5aSx6LSlIiBpY29uOiNjcml0aWNhbAogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApCiAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICkKICAgICkKCiAgICBnbG9iYWwgX21oX2tleV9hdXRoX3Bhc3NlZCA9IGZhbHNlCiAgICBsb2NhbCBfZ3VhcmQgPSBfTUhLZXlHdWFyZCgpCiAgICBpZiAoX2d1YXJkLlZlcmlmeUtleSAiTWF4U2NyaXB05re35reG5bel5YW3IiAiNTU4MjQyZTc4ZGExMjdkMzVmZTQ2YWFkZjRmMjdjNWZkMTgzMjdmODViNTg5YWY1ZDBhYTI3YTEwMTZhZGJmNyIgImI0ZjY4NzJiZDczMiIpIGRvICgKICAgICAgICBfbWhfa2V5X2F1dGhfcGFzc2VkID0gdHJ1ZQogICAgKQopCgooCiAgICBzdHJ1Y3QgX01IVHJpYWxDaGVja2VyICgKICAgICAgICBwcml2YXRlCiAgICAgICAgZm4gX0dldFJlZyBrIHZOYW1lID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLk9wZW5TdWJLZXkgayBmYWxzZQogICAgICAgICAgICAgICAgaWYgc2sgIT0gdW5kZWZpbmVkIGRvICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCB2ID0gc2suR2V0VmFsdWUgdk5hbWUKICAgICAgICAgICAgICAgICAgICBzay5DbG9zZSgpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2IGFzIHN0cmluZykKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkCiAgICAgICAgKSwKICAgICAgICBmbiBfU2V0UmVnIGsgdk5hbWUgdmFsID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgcmVnID0gZG90TmV0Q2xhc3MgIk1pY3Jvc29mdC5XaW4zMi5SZWdpc3RyeSIKICAgICAgICAgICAgICAgIGxvY2FsIHNrID0gcmVnLkN1cnJlbnRVc2VyLkNyZWF0ZVN1YktleSBrCiAgICAgICAgICAgICAgICBpZiBzayAhPSB1bmRlZmluZWQgZG8gKAogICAgICAgICAgICAgICAgICAgIHNrLlNldFZhbHVlIHZOYW1lICh2YWwgYXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHNrLkNsb3NlKCkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSBjYXRjaCAoKQogICAgICAgICksCiAgICAgICAgZm4gX0dldEZpbGUgZlBhdGggPSAoCiAgICAgICAgICAgIHRyeSAoCiAgICAgICAgICAgICAgICBpZiBkb2VzRmlsZUV4aXN0IGZQYXRoIGRvICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCBmID0gb3BlbkZpbGUgZlBhdGggbW9kZToiciIKICAgICAgICAgICAgICAgICAgICBpZiBmICE9IHVuZGVmaW5lZCBkbyAoCiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsIHMgPSByZWFkTGluZSBmCiAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlIGYKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChzIGFzIHN0cmluZykKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkgY2F0Y2ggKCkKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZAogICAgICAgICksCiAgICAgICAgZm4gX1NldEZpbGUgZlBhdGggdmFsID0gKAogICAgICAgICAgICB0cnkgKAogICAgICAgICAgICAgICAgbG9jYWwgZiA9IG9wZW5GaWxlIGZQYXRoIG1vZGU6InciCiAgICAgICAgICAgICAgICBpZiBmICE9IHVuZGVmaW5lZCBkbyAoCiAgICAgICAgICAgICAgICAgICAgZm9ybWF0ICIlXG4iIHZhbCB0bzpmCiAgICAgICAgICAgICAgICAgICAgY2xvc2UgZgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIGNhdGNoICgpCiAgICAgICAgKSwKICAgICAgICBwdWJsaWMKICAgICAgICBmbiBWZXJpZnlUcmlhbCBzVGl0bGUgdG90YWxEYXlzIHNJZCA9ICgKICAgICAgICAgICAgdHJ5ICgKICAgICAgICAgICAgICAgIGxvY2FsIGR0Q2xhc3MgPSBkb3ROZXRDbGFzcyAiU3lzdGVtLkRhdGVUaW1lIgogICAgICAgICAgICAgICAgbG9jYWwgbm93ID0gZHRDbGFzcy5VdGNOb3cKICAgICAgICAgICAgICAgIGxvY2FsIG5vd1N0ciA9IG5vdy5Ub1N0cmluZyAieXl5eS1NTS1kZCBISDptbTpzcyIKICAgICAgICAgICAgICAgIGxvY2FsIHJlZ1BhdGggPSAiU29mdHdhcmVcXE1vSGVTY3JpcHRcXFRyaWFsc1xcIiArIHNJZAogICAgICAgICAgICAgICAgbG9jYWwgY2FjaGVGaWxlID0gKGdldERpciAjcGx1Z2NmZykgKyAiLy50cmlhbF8iICsgc0lkICsgIi5saWMiCiAgICAgICAgICAgICAgICBsb2NhbCBfbmwgPSAoZG90TmV0Q2xhc3MgIlN5c3RlbS5FbnZpcm9ubWVudCIpLk5ld0xpbmUKCiAgICAgICAgICAgICAgICBsb2NhbCByU3RhcnQgPSBfR2V0UmVnIHJlZ1BhdGggIlN0YXJ0VGltZSIKICAgICAgICAgICAgICAgIGxvY2FsIGZTdGFydCA9IF9HZXRGaWxlIGNhY2hlRmlsZQogICAgICAgICAgICAgICAgbG9jYWwgc3RhcnRTdHIgPSBpZiAoclN0YXJ0ICE9IHVuZGVmaW5lZCBhbmQgclN0YXJ0ICE9ICIiKSB0aGVuIHJTdGFydCBlbHNlIGZTdGFydAoKICAgICAgICAgICAgICAgIGlmIHN0YXJ0U3RyID09IHVuZGVmaW5lZCBvciBzdGFydFN0ciA9PSAiIiB0aGVuICgKICAgICAgICAgICAgICAgICAgICBfU2V0UmVnIHJlZ1BhdGggIlN0YXJ0VGltZSIgbm93U3RyCiAgICAgICAgICAgICAgICAgICAgX1NldEZpbGUgY2FjaGVGaWxlIG5vd1N0cgogICAgICAgICAgICAgICAgICAgIF9TZXRSZWcgcmVnUGF0aCAiTGFzdFJ1biIgbm93U3RyCiAgICAgICAgICAgICAgICAgICAgbG9jYWwgbXNnID0gIuKPsyDjgJDor5XnlKjniYjov5DooYzmj5DnpLrjgJEiICsgX25sICsgX25sICsgIuasoui/juS9v+eUqOOAjCIgKyBzVGl0bGUgKyAi44CN77yBIiArIF9ubCArIF9ubCArICLil48g6K+V55So5pyf6ZmQ77yaIiArICh0b3RhbERheXMgYXMgc3RyaW5nKSArICIg5aSpIiArIF9ubCArICLil48g5r+A5rS754q25oCB77ya6aaW5qyh5ZCv5Yqo77yI6K+V55So5pyf5bey5r+A5rS777yJIiArIF9ubCArICLil48g5Ymp5L2Z5pe26Ze077ya57qmICIgKyAodG90YWxEYXlzIGFzIHN0cmluZykgKyAiIOWkqSIgKyBfbmwgKyBfbmwgKyAi6K+V55So5Yiw5pyf5ZCO5bCG5YGc5q2i6L+Q6KGM77yM5aaC6ZyA5q2j5byP5o6I5p2D6K+36IGU57O75L2c6ICF44CCIgogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VCb3ggbXNnIHRpdGxlOiLor5XnlKjniYjov5DooYzmj5DnpLoiIGljb246I2luZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWUKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICAgICBsb2NhbCByTGFzdCA9IF9HZXRSZWcgcmVnUGF0aCAiTGFzdFJ1biIKICAgICAgICAgICAgICAgIGlmIHJMYXN0ICE9IHVuZGVmaW5lZCBhbmQgckxhc3QgIT0gIiIgZG8gKAogICAgICAgICAgICAgICAgICAgIHRyeSAoCiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsIGxhc3REdCA9IGR0Q2xhc3MuUGFyc2Ugckxhc3QKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm93IDwgKGxhc3REdC5BZGRNaW51dGVzIC0xMC4wKSBkbyAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbCBtc2cgPSAi4p2MIOOAkOWuieWFqOitpuWRiuOAkSIgKyBfbmwgKyBfbmwgKyAi5qOA5rWL5Yiw6K6h566X5py657O757uf5pe26ZKf5a2Y5Zyo5byC5bi45Zue5ouo77yBIiArIF9ubCArICLor5XnlKjmnJ/pqozor4HlpLHotKXvvIzohJrmnKzlt7Lnu4jmraLov5DooYzjgIIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQm94IG1zZyB0aXRsZToi6K+V55So6aqM6K+B5byC5bi4IiBpY29uOiNjcml0aWNhbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICApIGNhdGNoICgpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICBfU2V0UmVnIHJlZ1BhdGggIkxhc3RSdW4iIG5vd1N0cgoKICAgICAgICAgICAgICAgIGxvY2FsIHN0YXJ0RHQgPSBkdENsYXNzLlBhcnNlIHN0YXJ0U3RyCiAgICAgICAgICAgICAgICBsb2NhbCBzcGFuID0gbm93LlN1YnRyYWN0IHN0YXJ0RHQKICAgICAgICAgICAgICAgIGxvY2FsIGRheXNQYXNzZWQgPSBzcGFuLlRvdGFsRGF5cwogICAgICAgICAgICAgICAgbG9jYWwgcmVtYWluRGF5cyA9IHRvdGFsRGF5cyAtIGRheXNQYXNzZWQKCiAgICAgICAgICAgICAgICBpZiByZW1haW5EYXlzIDw9IDAuMCB0aGVuICgKICAgICAgICAgICAgICAgICAgICBsb2NhbCBtc2cgPSAi4p2MIOOAkOivleeUqOacn+W3sue7k+adn+OAkSIgKyBfbmwgKyBfbmwgKyAi5oKo55qE44CMIiArIHNUaXRsZSArICLjgI0iICsgKHRvdGFsRGF5cyBhcyBzdHJpbmcpICsgIiDlpKnor5XnlKjmnJ/lt7Lnu5PmnZ/vvIEiICsgX25sICsgIuiEmuacrOW3suWBnOatoui/kOihjOOAgiIgKyBfbmwgKyBfbmwgKyAi5aaC6ZyA57un57ut5L2/55So77yM6K+36IGU57O75L2c6ICF6I635Y+W5q2j5byP5ZWG5Lia5o6I5p2D44CCIgogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VCb3ggbXNnIHRpdGxlOiLor5XnlKjlt7LliLDmnJ8iIGljb246I2NyaXRpY2FsCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgICAgICApIGVsc2UgKAogICAgICAgICAgICAgICAgICAgIGxvY2FsIHJlbWFpbkludCA9IChjZWlsIHJlbWFpbkRheXMpIGFzIGludGVnZXIKICAgICAgICAgICAgICAgICAgICBpZiByZW1haW5JbnQgPCAxIGRvIHJlbWFpbkludCA9IDEKICAgICAgICAgICAgICAgICAgICBsb2NhbCBtc2cgPSAi4o+zIOOAkOivleeUqOeJiOi/kOihjOaPkOekuuOAkSIgKyBfbmwgKyBfbmwgKyAi5oKo5q2j5Zyo5L2/55So55qE5piv44CMIiArIHNUaXRsZSArICLjgI3or5XnlKjniYjvvIEiICsgX25sICsgX25sICsgIuKXjyDor5XnlKjmnJ/pmZDvvJoiICsgKHRvdGFsRGF5cyBhcyBzdHJpbmcpICsgIiDlpKkiICsgX25sICsgIuKXjyDliankvZnml7bpl7TvvJrnuqYgIiArIChyZW1haW5JbnQgYXMgc3RyaW5nKSArICIg5aSpIiArIF9ubCArIF9ubCArICLor5XnlKjliLDmnJ/lkI7lsIblgZzmraLov5DooYzvvIzlpoLpnIDmraPlvI/mjojmnYPor7fogZTns7vkvZzogIXjgIIiCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUJveCBtc2cgdGl0bGU6IuivleeUqOeJiOi/kOihjOaPkOekuiIgaWNvbjojaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIGNhdGNoICgKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgICAgICkKICAgICAgICApCiAgICApCiAgICBnbG9iYWwgX21oX3RyaWFsX2F1dGhfcGFzc2VkID0gZmFsc2UKICAgIGxvY2FsIF9taENoZWNrZXIgPSBfTUhUcmlhbENoZWNrZXIoKQogICAgaWYgKF9taENoZWNrZXIuVmVyaWZ5VHJpYWwgIk1heFNjcmlwdOa3t+a3huW3peWFtyIgMyAiNWEyZjM5ZjZhZDA2IikgZG8gKAogICAgICAgIF9taF90cmlhbF9hdXRoX3Bhc3NlZCA9IHRydWUKICAgICkKKQoKaWYgKF9taF9rZXlfYXV0aF9wYXNzZWQgPT0gdHJ1ZSBhbmQgX21oX3RyaWFsX2F1dGhfcGFzc2VkID09IHRydWUpIGRvICgKCnRyeSAoZGVzdHJveURpYWxvZyBGa214MDFjeSApIGNhdGNoICgpCnJvbGxvdXQgRmtteDAxY3kgIuefv+ajieadv+WQiumhtiIgd2lkdGg6MHg4QyBoZWlnaHQ6MHhCQwooCglidXR0b24gYnRuMSAiWyAg5LiAICDplK4gIOeUnyAg5oiQICBdIiBwb3M6WzAsMzVdIHdpZHRoOjE1NSBoZWlnaHQ6MzAgdG9vbFRpcDoi6K+36YCJ5oup5bmz6Z2iIgoJYnV0dG9uIGJ0bjIgIlsgIEwgIEUgIEQgICDnga8gIOadvyAgXSIgcG9zOlswLDcwXSB3aWR0aDoxNTUgaGVpZ2h0OjMwIHRvb2xUaXA6Iuivt+mAieaLqemcgOimgeeUn+aIkOeBr+adv+eahOmdoiIKCWNoZWNrYnV0dG9uIGJ0YyAiWyAg5bu6ICDnu4QgIOW8gCAg5YWzICBdIiBwb3M6WzAsMTA1XSB3aWR0aDoxNTUgaGVpZ2h0OjMwIGVuYWJsZWQ6dHJ1ZSBjaGVja2VkOmZhbHNlCgoJc3Bpbm5lciBzcGYgIumVv+W6piIgcG9zOlsweEEsMHhBXSB3aWR0aDoweDQyIGhlaWdodDoweDEwIHJhbmdlOlswLDEwMDAwLCA0MDBdIHR5cGU6I2ludGVnZXIKCXNwaW5uZXIgc3BoICLlrr3luqYiIHBvczpbMHg1NywweEFdIHdpZHRoOjB4NDIgaGVpZ2h0OjB4MTAgcmFuZ2U6WzAsMTAwMDAsIDQwMF0gdHlwZTojaW50ZWdlcgoKCUltZ1RhZyBJbWdfbWFwIHdpZHRoOjI3MCBoZWlnaHQ6MjAgICBwb3M6Wy01LDE0MF0gYml0bWFwOihiaXRtYXAgMSAxIGNvbG9yOihjb2xvciAxMDAgMTQwIDE4MCkpICBlbmFibGVkOmZhbHNlCiAgICBoeXBlcmxpbmsgbGIxICLkvb/nlKjmlZnnqIsiIHBvczpbMCwxNDNdICBjb2xvcjooY29sb3IgMjUwIDI1MCAyNTApICAgY29sb3I6KGNvbG9yIDI1MCAyNTAgMjUwKSAgYWRkcmVzczoiaHR0cDovL3d3dy5ma214ZHMuY24vaHRtbC8yMDE5L2ptXzA2MjAvMjUzLmh0bWwiICBob3ZlcmNvbG9yOihjb2xvciAyNTAgMjUwIDI1MCkKCglmbiBGaXhUcmFuc2Zvcm1CeUZhY2UgZmFjZSA9CgkoCgkJCWlmIGNsYXNzb2YgZmFjZSA9PSBFZGl0YWJsZV9tZXNoIHRoZW4gKG5mID0gdHJ5KGdldEZhY2VOb3JtYWwgZmFjZSAoZ2V0RmFjZVNlbGVjdGlvbiAkIGFzIGFycmF5KVsxXSljYXRjaChnZXRGYWNlTm9ybWFsIGZhY2UgMSkpCgkJCWlmIGNsYXNzb2YgZmFjZSA9PSBFZGl0YWJsZV9Qb2x5IHRoZW4gKG5mID0gdHJ5KHBvbHlvcC5nZXRGYWNlTm9ybWFsIGZhY2UgKHBvbHlvcC5nZXRGYWNlU2VsZWN0aW9uIGZhY2UgYXMgYXJyYXkpWzFdKWNhdGNoKHBvbHlvcC5nZXRGYWNlTm9ybWFsIGZhY2UgMSkpCgkJCWZjPWZhY2UucG9zCgkJCXh2ID0gbm9ybWFsaXplIChjcm9zcyBuZiBbMCwwLDFdKQoJCQl5diA9IG5vcm1hbGl6ZSAoY3Jvc3MgbmYgeHYpCgkJCWFjPVswLDAsMF0KCgkJCWZhY2UudHJhbnNmb3JtKj1pbnZlcnNlIChtYXRyaXgzIHh2IHl2IG5mIGFjKQoJCQlSZXNldFhGb3JtIGZhY2UKCQkJY29sbGFwc2VzdGFjayBmYWNlCgkJCWZhY2UudHJhbnNmb3JtPShtYXRyaXgzIHh2IHl2IG5mIGFjKQoJCQlmYWNlLnBvcz1mYwoJKQoKCW9uIEZrbXgwMWN5IG9wZW4gIGRvCgkoCgl0cnkKCSgKICAgICBDa291VHViaWFvIEZrbXgwMWN5CgkpCgljYXRjaChtZXNzYWdlQm94ICLmk43kvZzplJnor68iKQogICAgKQoKCWxvY2FsIGJhc2UgPSB1bmRlZmluZWQKCglsb2NhbCBmbG9vclNwYWNlID0gdW5kZWZpbmVkCglsb2NhbCBwX1dpZHRoID0gIDMwMC4wCgoJbG9jYWwgcF9XaWR0aFIJPSAzMDAuMAoKCWxvY2FsIHBfTGVuZ3RoID0zMDAuMAoJbG9jYWwgcF9MZW5ndGhSID0zMDAuMAoKCWxvY2FsIHBfR2FwTGVuZ3RoPSAwLjAKCglsb2NhbCBwYXRXaWR0aCA9IHVuZGVmaW5lZAoKCWxvY2FsIHBfUm93T2Zmc2V0ID0yMC4wCgoJbG9jYWwgcF9PZmZzZXRMZW5ndGggPTAuMAoKCWxvY2FsIHBfT2Zmc2V0V2lkdGggPTAuMAoKCWxvY2FsIHBhdExlbmd0aCA9IHVuZGVmaW5lZAoJbG9jYWwgcGF0T3JpZ2luID0gdW5kZWZpbmVkCgoJbG9jYWwgZmxvb3JPYmplY3QgPSB1bmRlZmluZWQKCglsb2NhbCBmbG9vck9iamVjdE9sZCA9IHVuZGVmaW5lZAoKCWxvY2FsIG9iak9sZCA9IHVuZGVmaW5lZAoKCWxvY2FsIG9sZE1vZGlmaWVycyA9ICMoKQoKCWxvY2FsIHpPZmZzZXQgPSB1bmRlZmluZWQKCglmbiBldmFsdWF0ZVBhcmFtZXRlcnMgPSAoCgoJCXBfV2lkdGggPSAgc3BoLnZhbHVlCgoJCXBfV2lkdGhSCT0gc3BoLnZhbHVlCgoJCXBfTGVuZ3RoID0gc3BmLnZhbHVlCgkJcF9MZW5ndGhSID1zcGYudmFsdWUKCQlwX1Jvd09mZnNldCA9MjAKCgkJcF9PZmZzZXRMZW5ndGggPTAuMAoKCQlwX09mZnNldFdpZHRoID0wLjAKCgkpCgoJZm4gcm5kID0gKCByYW5kb20gLjAgMS4JKQoKCWZuIHVybmQgPSAoIHJhbmRvbSAtMS4gMS4gKQoKCWZuIGZsaXBDb2luID0gKCByYW5kb20gMCAxID09IDAgKQoKCWZuIG1heEFuZ2xlIHcgbCBnID0gKAoJbG9jYWwgeCA9IHNxcnQgKHcqdyAqIC4yNSArIGwqbCAqIC4yNSkKCWxvY2FsIG0gPSAodyArIGcpICogLjUKCWlmIHggPCBtIHRoZW4KCQlyZXR1cm4gMTgwLjAKCWxvY2FsIGEgPSBhdGFuICh3IC8gbCkKCWxvY2FsIGIgPSBhY29zIChtIC8geCkKCTkwLjAgLSBhIC0gYgoJKQoJZm4gc3ByZWFkQ3VydmUgc3ByZWFkIHZhbCA9ICgKCQlpZiBzcHJlYWQgPCAwLjAwMDAxIHRoZW4gcmV0dXJuIDAuCgkJaWYgc3ByZWFkID4gMC45OTk5OSB0aGVuIHJldHVybiAxLgoJCWlmIHZhbCA8IDEuIC0gc3ByZWFkIHRoZW4KCQkJcmV0dXJuICgoc3ByZWFkIC8gKDEuIC0gc3ByZWFkKSkgKiB2YWwpCgkJZWxzZQoJCQlyZXR1cm4gKCgxLiAtIHNwcmVhZCkgKiAodmFsIC0gMS4pIC8gc3ByZWFkICsgMS4pCgkpCgoJZm4gcmFuZCBmcm9tVmFsIHRvVmFsIHNwcmVhZCA9ICgKCQlmcm9tVmFsICsgKHRvVmFsIC0gZnJvbVZhbCkgKiAoc3ByZWFkQ3VydmUgKHJuZCgpKSBzcHJlYWQpCgkpCgoJZm4gaW5pdE5vZGVzIHRvTm9kZSBvbGRGbG9vcjp1bmRlZmluZWQgPSAoCgoJCWlmIG9sZEZsb29yICE9IHVuZGVmaW5lZCB0aGVuICgKCQkJZmxvb3JPYmplY3QgPSBvbGRGbG9vcgoKCQkJb2xkTW9kaWZpZXJzID0gIygpCgkJCWZvciBpIGluIDEgdG8gZmxvb3JPYmplY3QubW9kaWZpZXJzLmNvdW50IGRvCgkJCQlvbGRNb2RpZmllcnNbaV0gPSBmbG9vck9iamVjdC5tb2RpZmllcnNbaV0KCgkJCXdoaWxlIGZsb29yT2JqZWN0Lm1vZGlmaWVycy5jb3VudCA+IDAgZG8KCQkJCWRlbGV0ZU1vZGlmaWVyIGZsb29yT2JqZWN0IDEKCgkJCXNldE1lc2ggZmxvb3JPYmplY3QgbnVtdmVydHM6MCBudW1mYWNlczowCgkJCXVwZGF0ZSBmbG9vck9iamVjdAoJCQlmbG9vck9iamVjdC50cmFuc2Zvcm0gPSBtYXRyaXgzIDEKCQkpIGVsc2UgKAoJCQlmbG9vck9iamVjdCA9IGVkaXRhYmxlX21lc2ggbmFtZToodW5pcXVlbmFtZSAi55+/5qOJ5p2/X1NlYV9OX09iamVjdCIpCgkJKQoKCQliYXNlID0gZWRpdGFibGVfbWVzaCBuYW1lOih1bmlxdWVuYW1lICLnn7/mo4nmnb9fU2VhX05fVGVtcG9yYXJ5T2JqZWN0IikKCQlhdHRhY2ggYmFzZSAoY29weSB0b05vZGUpCgoJCXpPZmZzZXQgPSAwLjAKCQlsb2NhbCB4eVBvaW50CgkJZm9yIGkgaW4gMSB0byBnZXROdW1WZXJ0cyBiYXNlIGRvICgKCQkJeHlQb2ludCA9IGdldFZlcnQgYmFzZSBpCgkJCXpPZmZzZXQgKz0geHlQb2ludC56CgkJCXh5UG9pbnQueiA9IDAuMAoJCQlzZXRWZXJ0IGJhc2UgaSB4eVBvaW50CgkJKQoJCXpPZmZzZXQgLz0gZ2V0TnVtVmVydHMgYmFzZQoJKQoKCWZuIGNyZWF0ZU1hdHJpeDMgcCA9ICgKCQlsb2NhbCB4ID0gWzEsMCwwXQoJCWxvY2FsIHkgPSBbMCwxLDBdCgkJbG9jYWwgeiA9IFswLDAsMV0KCQlmbG9vclJvdGF0aW9uID0gcXVhdCAoMCkgegoJCXggKj0gZmxvb3JSb3RhdGlvbgoJCXkgKj0gZmxvb3JSb3RhdGlvbgoJCWZsb29yU3BhY2UgPSBNYXRyaXgzIHggeSB6IHAKCSkKCglmbiBjYWxjQm91bmRpbmdCb3ggPSAoCgkJYmIxID0gKGdldFZlcnQgYmFzZSAxKSAqIChpbnZlcnNlIGZsb29yU3BhY2UpCgkJYmIyID0gKGdldFZlcnQgYmFzZSAxKSAqIChpbnZlcnNlIGZsb29yU3BhY2UpCgoJCWxvY2FsIG51bSA9IGdldE51bVZlcnRzIGJhc2UKCQlsb2NhbCB2CgkJZm9yIGkgaW4gMSB0byBudW0gZG8gKAoJCQl2ID0gZ2V0VmVydCBiYXNlIGkKCQkJdiAqPSAoaW52ZXJzZSBmbG9vclNwYWNlKQoJCQlpZiBiYjEueCA8IHYueCB0aGVuIGJiMS54ID0gdi54CgkJCWVsc2UgaWYgYmIyLnggPiB2LnggdGhlbiBiYjIueCA9IHYueAoJCQlpZiBiYjEueSA+IHYueSB0aGVuIGJiMS55ID0gdi55CgkJCWVsc2UgaWYgYmIyLnkgPCB2LnkgdGhlbiBiYjIueSA9IHYueQoJCSkKCQliYjEueiA9IGJiMi56ID0gMAoJCXBhdE9yaWdpbiA9IFtiYjIueCwgYmIxLnksIDBdCgkJcGF0V2lkdGggPSBiYjIueSAtIGJiMS55CgkJcGF0TGVuZ3RoID0gYmIxLnggLSBiYjIueAoJKQoJZm4gY3JlYXRlUG9seWdvbiBwMSBwMiBpZCA9ICgKCQlsb2NhbCBudW0gPSBnZXROdW1WZXJ0cyBmbG9vck9iamVjdCArIDEKCQlzZXROdW1WZXJ0cyBmbG9vck9iamVjdCAobnVtICsgMykgdHJ1ZQoJCXNldFZlcnQgZmxvb3JPYmplY3QgKG51bSAgKSBbcDEueCxwMi55LDBdCgkJc2V0VmVydCBmbG9vck9iamVjdCAobnVtKzEpIHAyCgkJc2V0VmVydCBmbG9vck9iamVjdCAobnVtKzIpIFtwMi54LHAxLnksMF0KCQlzZXRWZXJ0IGZsb29yT2JqZWN0IChudW0rMykgcDEKCQltZXNob3AuY3JlYXRlUG9seWdvbiBmbG9vck9iamVjdCAjKG51bSwgbnVtKzEsIG51bSsyLCBudW0rMykgbWF0SUQ6aWQKCgkpCgoJZm4gY3JlYXRlUGF0dGVybl8wMSA9ICgKCQlwbGFua1BvcyA9ICMoKQoJCXBsYW5rUm90ID0gIygpCgkJcGxhbmtUaWx0ID0gIygpCgkJcGxhbmtMZW5NaW4gPSAjKCkKCQlwbGFua0xlbk1heCA9ICMoKQoKCQlsb2NhbCB0b3RhbFdpZHRoID0gLShwX1dpZHRoKQoKCQlsb2NhbCB4LHkseix3LHAxLHAyLHAzLHA0LGNlbnRlcixyb3QscSxtaW5MLG1heEwscFgscFksclgsclkscixtYXhBLG1heEIsdXZSYW5kCgkJbG9jYWwgcm93ID0gMAoJCWxvY2FsIGNvdW50ID0gMQoJCWxvY2FsIGxlbmd0aFBsdXNHYXAgPSBwX0xlbmd0aAoJCXdoaWxlIHRvdGFsV2lkdGggPCAocGF0V2lkdGggKyBwX1dpZHRoICkgZG8KCQkoCgoJCQl4ID0gcF9XaWR0aAoKCQkJeSA9IDAuMAoJCQl0b3RhbExlbmd0aCA9IG1vZCAoLShsZW5ndGhQbHVzR2FwKSAqIHBfUm93T2Zmc2V0ICogcm93KSBsZW5ndGhQbHVzR2FwCgkJCXRvdGFsTGVuZ3RoICs9IC1sZW5ndGhQbHVzR2FwCgoJCQl3aGlsZSB0b3RhbExlbmd0aCA8IChwYXRMZW5ndGggKyBsZW5ndGhQbHVzR2FwKSBkbyAoCgoJCQkJeiA9IHJhbmQgcF9MZW5ndGhSIHBfTGVuZ3RoICgwLjUpCgkJCQl3ID0gcF9HYXBMZW5ndGgKCgkJCQlyWCA9IDAKCgkJCQlyWSA9IDAKCgkJCQlpZiBmbGlwQ29pbigpIHRoZW4gclggPSAtclgKCQkJCWlmIGZsaXBDb2luKCkgdGhlbiByWSA9IC1yWQoJCQkJcFggPSB0b3RhbExlbmd0aCAtIHJYCgkJCQlwWSA9IHRvdGFsV2lkdGggLSByWQoKCQkJCXAxID0gW3BYLCAgIHBZK3gsIDBdICsgcGF0T3JpZ2luCgkJCQlwMiA9IFtwWCt6LCBwWSwgICAwXSArIHBhdE9yaWdpbgoJCQkJcDMgPSBbcDEueCxwMi55LDBdCgkJCQlwNCA9IFtwMi54LHAxLnksMF0KCgkJCQljcmVhdGVQb2x5Z29uIHAxIHAyIGNvdW50CgoJCQkJY2VudGVyID0gWyhwWCt6LzIuKSwgKHBZK3gvMi4pLCAwXSArIHBhdE9yaWdpbgoJCQkJcGxhbmtQb3NbY291bnRdID0gY2VudGVyCgoJCQkJY291bnQgKz0gMQoJCQkJdG90YWxMZW5ndGggKz0geiArIHcKCQkJKQoKCQkJcm93ICs9IDEKCQkJdG90YWxXaWR0aCArPSB4ICsgeQoJCSkKCSkKCWZuIGNyZWF0ZUZsb29yIG9iaiB4eG9iaiBvbGRGbG9vcjp1bmRlZmluZWQgPSAoCgoJKAoKCQlsb2NhbCBwID0gb2JqLnBvcwoJCWV2YWx1YXRlUGFyYW1ldGVycygpCgkJY3JlYXRlTWF0cml4MyBwCgoJCWluaXROb2RlcyBvYmogb2xkRmxvb3I6b2xkRmxvb3IKCQljYWxjQm91bmRpbmdCb3goKQoJCWNyZWF0ZVBhdHRlcm5fMDEoKQoKCQlmbG9vck9iamVjdC5wb3MgPSBbcC54LCBwLnksIDAuMF0KCQlhZGRNb2RpZmllciBiYXNlIChTaGVsbCBpbm5lckFtb3VudDoxLiBvdXRlckFtb3VudDoxLikKCQlmbG9vck9iamVjdCAqIGJhc2UKCgkJbG9jYWwgYWxsID0gI3t9CgkJYWxsLmNvdW50ID0gZ2V0TnVtVmVydHMgZmxvb3JPYmplY3QKCQlhbGwgPSAtYWxsCgoJCW1lc2hvcC53ZWxkVmVydHNCeVRocmVzaG9sZCBmbG9vck9iamVjdCBhbGwgMC4xCgoJCWRlbGV0ZSBiYXNlCgkJcGxhbmtQb3MgPSAjKCkKCQlwbGFua1JvdCA9ICMoKQoJCXBsYW5rVGlsdCA9ICMoKQoJCXBsYW5rVGlsdFN0ciA9ICMoKQoJCXBsYW5rTGVuTWluID0gIygpCgkJcGxhbmtMZW5NYXggPSAjKCkKCgkJZW5hYmxlU2NlbmVSZWRyYXcoKQoKCQlmbG9vck9iamVjdE9sZCA9IGZsb29yT2JqZWN0CgkJb2JqT2xkID0geHhvYmoKCQkpCgkJZmxvb3JPYmplY3RPbGQKCgkpCgoJb24gYnRuMSBwcmVzc2VkIGRvCgkoCgkJCSgKCXRyeQooCgkJCW1heCBjcmVhdGUgbW9kZQoJCQlpc3BvbHkgPSBmYWxzZQoJCQlOZXdPYmogPSAiIgoJCQlvYmogPSBmb3IgaSBpbiBzZWxlY3Rpb24gY29sbGVjdCBpCgkJCWlmIG9iai5jb3VudCA9PSAxIGFuZCBzdWJvYmplY3RMZXZlbCA9PSA0IGFuZCBjbGFzc29mIG9ialsxXSA9PSBFZGl0YWJsZV9Qb2x5IHRoZW4KCQkJKAoJCQkJc2VsZmFjZSA9IHBvbHlvcC5nZXRGYWNlU2VsZWN0aW9uIG9ialsxXSBhcyBhcnJheQoJCQkJaWYgc2VsZmFjZS5jb3VudCA9PSAxIHRoZW4KCQkJCSgKCQkJCQluZXdOYW1lID0gdW5pcXVlbmFtZSBvYmpbMV0ubmFtZQoJCQkJCXBvbHlPcC5kZXRhY2hGYWNlcyBvYmpbMV0gI3tzZWxmYWNlWzFdfSBhc05vZGU6dHJ1ZSBkZWxldGU6ZmFsc2UgbmFtZTpuZXdOYW1lCgkJCQkJTmV3T2JqID0gZ2V0bm9kZWJ5bmFtZSBuZXdOYW1lCgkJCQkJaXNwb2x5ID0gdHJ1ZQoJCQkJKQoJCQkpCgkJCWlmIGlzcG9seSB0aGVuIChvYmoyID0gTmV3T2JqKSBlbHNlIChvYmoyID0gY29weSBvYmpbMV0pCgkJCWlmIGNsYXNzb2Ygb2JqMiAhPSBFZGl0YWJsZV9Qb2x5IHRoZW4KCQkJKAoKCQkJCWNvbnZlcnRUbyBvYmoyIEVkaXRhYmxlX1BvbHkKCgkJCSkKCgkJCUZpeFRyYW5zZm9ybUJ5RmFjZSBvYmoyCgkJCUNlbnRlclBpdm90IG9iajIKCQkJY2MgPSBjb3B5IG9iajIKCQkJY2MudHJhbnNmb3JtID0gKG1hdHJpeDMgWzEsMCwwXSBbMCwxLDBdIFswLDAsMV0gWzAsMCwwXSkKCgkJCW5ld29iaiA9IGNyZWF0ZUZsb29yIGNjIG9ialsxXQoKCQkJV29ybGRBbGlnblBpdm90IG5ld29iagoJCQlDZW50ZXJQaXZvdCBuZXdvYmoKCQkJbmV3b2JqLnBpdm90ID0gY2MucGl2b3QKCQkJbmV3b2JqLnRyYW5zZm9ybSA9IG9iajIudHJhbnNmb3JtCgkJCWNvbnZlcnRUbyBuZXdvYmogRWRpdGFibGVfUG9seQoJCQlkZWxldGUgb2JqMjtkZWxldGUgY2MKCQkJc2VsZWN0IG5ld29iagoKCQkJaWYgIHNlbGVjdGlvbiAuY291bnQgPT0gMSB0aGVuCgkJCSgKCgkJCQltYXggbW9kaWZ5IG1vZGUKCQkJCW1hY3JvcyAucnVuICJNb2RpZmllciBTdGFjayIgIkNvbnZlcnRfdG9fUG9seSIKCQkJCXN1Ym9iamVjdExldmVsID0gMwoJCQkJbWF4IHNlbGVjdCBhbGwKCQkJCXN1Ym9iamVjdExldmVsID0gMgoJCQkJbWF4IHNlbGVjdCBpbnZlcnQKCQkJCUEgPSBuZXdvYmouRWRpdGFibGVQb2x5IC5HZXRTZWxlY3Rpb24gI0VkZ2UKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLkNvbnZlcnRTZWxlY3Rpb24gI0VkZ2UgI0ZhY2UKCQkJCXN1Ym9iamVjdExldmVsID0gNAoJCQkJbmV3b2JqLmluc2V0VHlwZSA9IDEKCQkJCW5ld29iai5pbnNldEFtb3VudCA9IDgKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLmJ1dHRvbk9wICNJbnNldAoJCQkJRCA9IG5ld29iai5FZGl0YWJsZVBvbHkgLkdldFNlbGVjdGlvbiAjZmFjZQoJCQkJbmV3b2JqLkVkaXRhYmxlUG9seSAuQ29udmVydFNlbGVjdGlvbiAjRmFjZSAjRWRnZQoJCQkJc3Vib2JqZWN0TGV2ZWwgPSAweDIKCQkJCUIgPSBuZXdvYmouRWRpdGFibGVQb2x5IC5HZXRTZWxlY3Rpb24gI0VkZ2UKCQkJCXN1Ym9iamVjdExldmVsID0gMHg0CgkJCQluZXdvYmouZmFjZUV4dHJ1ZGVIZWlnaHQgPSAweDMKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLmJ1dHRvbk9wICNFeHRydWRlCgkJCQlDID0gbmV3b2JqLkVkaXRhYmxlUG9seSAuR2V0U2VsZWN0aW9uICNmYWNlCgkJCQlzdWJvYmplY3RMZXZlbCA9IDB4MgoJCQkJbmV3b2JqLmVkZ2VDaGFtZmVyID0gMHgyCgkJCQluZXdvYmouZWRnZUNoYW1mZXJTZWdtZW50cyA9IDB4MgoJCQkJbmV3b2JqLkVkaXRhYmxlUG9seSAuYnV0dG9uT3AgI0NoYW1mZXIKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLlNldFNlbGVjdGlvbiAjRWRnZSAoQSApCgkJCQluZXdvYmouZWRnZUV4dHJ1ZGVXaWR0aCA9IDEuNzU2MzUKCQkJCW5ld29iai5lZGdlRXh0cnVkZUhlaWdodCA9IDAuNjYKCQkJCW5ld29iai5FZGl0YWJsZVBvbHkgLmJ1dHRvbk9wICNFeHRydWRlCgkJCQluZXdvYmouRWRpdGFibGVQb2x5IC5Db252ZXJ0U2VsZWN0aW9uICNFZGdlICNGYWNlCgkJCQlzdWJvYmplY3RMZXZlbCA9IDB4NAoJCQkJRiA9IG5ld29iai5FZGl0YWJsZVBvbHkgLkdldFNlbGVjdGlvbiAjZmFjZQoJCQkJbmV3b2JqLkVkaXRhYmxlUG9seSAuU2V0U2VsZWN0aW9uICNmYWNlIChDICkKCQkJCW5ld05hbWUgPSB1bmlxdWVuYW1lICLnn7/mo4nmnb9fU2VhX05fIgoJCQkJcG9seU9wIC5kZXRhY2hGYWNlcyBuZXdvYmogbmV3b2JqLnNlbGVjdGVkZmFjZXMgYXNOb2RlOm9uIGRlbGV0ZTpvbiBuYW1lOm5ld05hbWUKCQkJCVRlbXBfS3VhbmdNaWFuQmFuID0gZ2V0bm9kZWJ5bmFtZSBuZXdOYW1lCgkJCQluZXdvYmouRWRpdGFibGVQb2x5IC5TZXRTZWxlY3Rpb24gI2ZhY2UgKEYgKQoJCQkJbWFjcm9zIC5ydW4gIlBvbHlUb29scyIgInNpbWlsYXIiCgkJCQluZXdOYW1lMiA9IHVuaXF1ZW5hbWUgIuefv+ajieadv1/pu5HmnaFfU2VhX05fIgoJCQkJcG9seU9wIC5kZXRhY2hGYWNlcyBuZXdvYmogbmV3b2JqLnNlbGVjdGVkZmFjZXMgYXNOb2RlOm9uIGRlbGV0ZTpvbiBuYW1lOm5ld05hbWUyCgkJCQlUZW1wX0t1YW5nTWlhbkJhbl9IZWlUaWFvID0gZ2V0bm9kZWJ5bmFtZSBuZXdOYW1lMgoJCQkJc3Vib2JqZWN0TGV2ZWwgPSAweDAKCQkJCW5ld29iai5OYW1lPXVuaXF1ZW5hbWUgIuefv+ajieadv1/pvpnpqqhfU2VhX05fIgoKCQkJCU1hdF9IZWlUaWFvID0gU3RhbmRhcmRtYXRlcmlhbCAoKQoJCQkJTWF0X0hlaVRpYW8uRGlmZnVzZSA9IGNvbG9yIDB4RiAweEYgMHhGCgkJCQlUZW1wX0t1YW5nTWlhbkJhbl9IZWlUaWFvLm1hdGVyaWFsID0gTWF0X0hlaVRpYW8KCQkJCU1hdF9Mb25nR3UgPSBTdGFuZGFyZG1hdGVyaWFsICgpCgkJCQlNYXRfTG9uZ0d1LkRpZmZ1c2UgPSBjb2xvciAweDUyIDB4NTYgMHg1OQoKCQkJCW5ld29iai5tYXRlcmlhbCA9IE1hdF9Mb25nR3UKCQkJCU1hdF9iYW4gPSBTdGFuZGFyZG1hdGVyaWFsICgpCgkJCQlNYXRfYmFuLkRpZmZ1c2UgPSBjb2xvciAweEZGIDB4RkYgMHhGRgoJCQkJVGVtcF9LdWFuZ01pYW5CYW4ubWF0ZXJpYWwgPSBNYXRfYmFuCgkJCQlzZWxlY3QgIyhuZXdvYmosIFRlbXBfS3VhbmdNaWFuQmFuLCBUZW1wX0t1YW5nTWlhbkJhbl9IZWlUaWFvKQoJCQkJZ3JvdXAgJAoKCQkJKQoJCSkKCWNhdGNoKG1lc3NhZ2VCb3ggIuaTjeS9nOmUmeivryIpCiAgICApCgoJKQoJb24gYnRuMiBwcmVzc2VkIGRvCgkoCgkJaWYgc3Vib2JqZWN0TGV2ZWwgPT0gMHg0IHRoZW4KCQkoCgkJCXBvbHlPcCAuZGV0YWNoRmFjZXMgJCAkLnNlbGVjdGVkZmFjZXMgYXNOb2RlOm9uIGRlbGV0ZTpvbiBuYW1lOiJMRUREZW5nIgoJCQltZWRpdE1hdGVyaWFscyBbMHgxXSA9IFN0YW5kYXJkICgpCgkJCW1lZGl0TWF0ZXJpYWxzIFsweDFdLnNlbGZJbGx1bUNvbG9yID0gY29sb3IgMHhGRiAweEZGIDB4RkYKCQkJbWVkaXRNYXRlcmlhbHMgWzB4MV0udHdvU2lkZWQgPSBvbgoJCQltZWRpdE1hdGVyaWFscyBbMHgxXS51c2VTZWxmSWxsdW1Db2xvciA9IG9uCgkJCSRMRUREZW5nKi5tYXRlcmlhbCA9IG1lZGl0TWF0ZXJpYWxzIFsweDFdCgkJKQoJKQoJb24gYnRjIGNoYW5nZWQgc3RhdGUgZG8KCSgKCQlpZiBzZWxlY3Rpb24gLmNvdW50ID4gMHgwIHRoZW4KCQkoCgkJCWlmIGJ0YyAuY2hlY2tlZCA9PSB0cnVlIHRoZW4KCQkJKAoJCQkJYnRjIC50ZXh0ID0gIuW3suaJk+W8gCIKCQkJCXRyeSAoZm9yIGEgaW4gc2VsZWN0aW9uIGRvIGlmIGlzZ3JvdXBoZWFkIGEgdGhlbiBzZXRncm91cG9wZW4gYSB0cnVlICljYXRjaCAoKQoJCQkJdHJ5IChvayApY2F0Y2ggKCkKCQkJKQoJCQllbHNlIGlmIGJ0YyAuY2hlY2tlZCA9PSBmYWxzZSB0aGVuCgkJCSgKCQkJCWJ0YyAudGV4dCA9ICLlt7LlhbPpl60iCgkJCQl0cnkgKGZvciBhIGluIG9iamVjdHMgZG8gaWYgaXNncm91cGhlYWQgYSB0aGVuIHNldGdyb3Vwb3BlbiBhIGZhbHNlICljYXRjaCAoKQoJCQkJdHJ5IChvayApY2F0Y2ggKCkKCQkJKQoJCSkKCQllbHNlIG1lc3NhZ2Vib3ggIuivt+mAieaLqeW8gOe7hOeJqeS9kyIKCSkKKQpjcmVhdGVEaWFsb2cgRmtteDAxY3kgIDE1NSAxNjUgMjIyIDIwMApjbGVhckxpc3RlbmVyICgpCik="
if _code.count > 0 do (
execute _code
)
)
)
local _runner = _st_60bf18()
_runner._ex_171884()
)
HWID硬件授权:进一步限制授权设备
程序的产品信息中还明确加入了 CPU / 主板 HWID 硬件锁节点授权,界面也提供了复制当前机器 HWID 的功能,HWID的意义很容易理解,传统激活码只判断“Key对不对”,那么同一个Key理论上可能被复制到不同电脑。而机器码授权则可以进一步将许可证和指定设备绑定。
对于收费插件作者来说,可以形成:账号/许可证 + HWID + 脚本保护,这样的授权体系,尤其是工作室内部工具、企业插件、定制脚本或者收费 MaxScript,这类授权方式会比单纯发一个密码更适合长期管理。
内置恶意MaxScript扫描:发现高危代码直接阻断
这个版本还有一个比较特别的功能:MalwareSecurityScanner,它并不是在脚本加密之后检查,而是在准备把代码加入脚本库、执行、混淆或者加密的时候进行安全预检。
从源码规则来看,扫描器重点检查磁盘格式化、DiskPart清盘、卷影副本删除、系统目录强制删除、物理磁盘访问、隐藏PowerShell执行、下载并执行代码等高风险特征,一旦脚本命中规则,程序会把它标记为高风险,并阻止继续执行、混淆或加密。
脚本库里的文件也不是“添加时检查一次就结束”。当用户准备再次运行脚本时,程序还会重新读取文件执行实时安全检查。如果文件后来被修改并命中危险规则,同样会阻止其进入3ds Max执行,因此它同时承担了一部分 3ds Max脚本安全卫士 的角色。
MoHe Script v1.0 适合哪些人使用?
如果只是下载几个免费 MaxScript 自己使用,那么很多功能可能用不上,但如果你属于 3ds Max插件开发者、MaxScript作者、工作室TD、商业脚本作者、3D工具开发者,这套思路就比较有价值。
尤其是准备销售自己脚本的开发者,以前可能需要分别寻找代码混淆工具、MSE转换工具、授权系统、试用系统和脚本管理器,现在可以把这些流程集中起来,需要注意的是,没有任何客户端代码保护方案能够承诺“绝对无法破解”。混淆、加密、MSE和授权的实际价值,是提高分析、复制和二次分发的成本,而不是宣称代码经过处理后永远无法还原。
免费下载:
总结:从MaxScript混淆工具升级成完整的3ds Max脚本安全工具箱
MoHe Script v1.0 最有意思的地方,在于它已经不局限于传统的“选择一个MS文件,然后点击混淆”,从实际来看,它把三级代码混淆、3ds Max原生MSE编译、运行密钥、试用期限、HWID授权基础、安全扫描、批量处理、脚本库以及3ds Max实时联动放进了一套程序。对于需要长期开发和商业分发 MaxScript 的作者,这种一体化工作流比单一代码混淆更有实际价值。




![年底收官巨献,AIGC行业全平台设计工具网站正式上线,助力创作者突破创作瓶颈,开启高效创作之旅[已下线]-MOHE素材库-设计行业的乐园,各类素材的矿山!](https://www.mohe-sc.com/wp-content/uploads/2024/12/Ai.turnfish.top_-800x450.jpg)


![百度网盘直链解析彻底解除百度云限速限制[利用IDM工具在线解析网页版]-MOHE素材库-设计行业的乐园,各类素材的矿山!](http://mohe-sc.com/wp-content/uploads/2021/07/baiduwangpan-400x273.png)










暂无评论内容