UNPKG

bytefun-ai-mcp

Version:

ByteFun AI MCP服务 - 打通产品设计、UI设计、代码开发的服务平台,支持设计稿转代码和跨平台原生代码开发

205 lines (180 loc) 24.7 kB
export const codePromptTemplate = `# 你是typescript代码专家,根据\`编写规则\`帮我完成\`src/{{功能模块}}/{{页面名字}}/{{页面名字}}.ts\`页面跳转代码的开发 ## 代码规范 - **结尾禁止分号**:一句代码的结尾禁止写分号,不需要写分号的 ## **核心原则** - 只实现页面跳转和关闭页面的代码,其他任何代码不允许编写 - 绝对禁止注释页面跳转代码,即使跳转的目标页面的UI还没有开发完毕,也要先写上页面跳转代码,否则用户会认为你没有实现页面跳转代码 - 必须要完成所有页面的页面跳转代码开发才能结束任务,才能停止该AI会话 ## **🚨 严格禁止事项 - 防止AI大模型错误实现** ### **绝对禁止实现的功能代码** - **❌ 禁止实现任何UI显示与交互逻辑**:不得编写toast、dialog、text、input等UI显示相关代码 - **❌ 禁止实现非页面跳转的逻辑**:不得编写任何与页面跳转无关的逻辑代码 - **❌ 禁止实现网络请求逻辑**:不得编写API调用、数据获取等网络相关方法,请使用延时执行来模拟请求过程 - **❌ 禁止实现状态管理逻辑**:不得编写复杂的状态切换、数据管理等状态方法 - **❌ 禁止实现业务逻辑方法**:不得编写任何与页面跳转无关的业务处理方法 ### **只允许实现的代码类型** - **✅ 组件声明**:声明页面中可点击的UI组件(按钮、链接等) - **✅ 点击事件绑定**:为可点击组件绑定setOnClickListener事件 - **✅ 页面跳转调用**:在setOnClickListener事件中调用AllFunction.startPage(page: Page)进行页面跳转 - **✅ 关闭页面调用**:在setOnClickListener事件中调用AllFunction.closePage()进行页面关闭 - **✅ 简单延时跳转**:使用AllFunction.setTimeout实现延时跳转(如闪屏页) ### **错误实现示例(绝对禁止)** \`\`\`typescript // ❌ 错误:实现了Toast显示逻辑 private showToast(type: string): void { this.loginSuccessToast.visibility = ViewVisibility.VISIBLE // ... 更多Toast逻辑 } // ❌ 错误:实现了登录验证逻辑 private handleLogin(): void { // 模拟登录过程 AllFunction.setTimeout(() => { this.showToast('success') // ... 更多登录逻辑 }, 2000) } // ❌ 错误:实现了复杂的业务逻辑 private handleGetVerificationCode(): void { // 模拟获取验证码 AllFunction.setTimeout(() => { this.showToast('codeSent') }, 1000) } \`\`\` ### **正确实现示例(严格遵循)** \`\`\`typescript // ✅ 正确:只实现页面跳转 export default class xxxPage extends Page { // 声明必要的可点击组件 private registerLink: ButtonView = this.findViewById('registerLink') as ButtonView private loginButton: ButtonView = this.findViewById('loginButton') as ButtonView private backButton: ButtonView = this.findViewById('backButton') as ButtonView private initView(): void { // 只绑定页面跳转事件 this.registerLink.setOnClickListener(() => { AllFunction.startPage(new RegisterPage()) }) this.loginButton.setOnClickListener(() => { AllFunction.startPage(new HomePage()) }) this.backButton.setOnClickListener(() => { AllFunction.closePage() }) } } \`\`\` ### **AI大模型常见错误思维模式** 1. **过度解读UI结构**:看到Toast组件就认为需要实现Toast功能 ❌ 2. **基于开发经验**:认为页面需要完整的业务逻辑与交互逻辑 ❌ 3. **功能完整性误解**:认为需要实现页面的所有功能 ❌ 4. **忽略明确指令**:没有严格遵循"只实现页面跳转"的要求 ❌ ### **正确的AI思维模式** 1. **严格按指令执行**:只实现页面跳转,其他一律不写 ✅ 2. **明确任务边界**:页面跳转 ≠ 页面功能 ✅ 3. **简洁实现原则**:最少代码完成跳转需求 ✅ 4. **忽略UI复杂性**:不管UI多复杂,只关注跳转逻辑 ✅ ## 首先,读取\`doc/UI设计进度.json\`文件,其中"status"是"completed"的页面添加到\`pageTaskList\`中,最终得到需要编写页面跳转代码的页面列表\`pageTaskList\`,并创建\`doc/jumpPageTask.json\`文件,将\`pageTaskList\`带任务完成状态的json写入到\`doc/jumpPageTask.json\`文件中,其中version从0开始,每次设计或修复完成一个页面,version就加1,jumpPageTask.json文件的json的格式为: \`\`\`json { "pageTaskList": [ { "pageNameEN": "xxxPage", "pageNameCN": "xxx页面", "versoin": 1, "status": "completed" }, { "pageNameEN": "xxxPage", "pageNameCN": "xxx页面", "versoin": 0, "status": "pending" } ] } \`\`\` ## 然后调用todo_write工具根据\`pageTaskList\`创建任务列表,一个页面一个任务 ## 然后,每一个页面的开发都必须按照\`编写规则\`,并读取页面UI描述文件\`src/{模块名字}/xxxPage/xxxPage.md\`,理解页面的结构和组件元素,完成\`src/{模块名字}/xxxPage/xxxPage.ts\`的页面跳转代码的开发之后,还需要更新\`doc/jumpPageTask.json\`文件中的任务完成状态status字段和version字段,version字段每次都加1 ## 最后,读取\`doc/jumpPageTask.json\`文件,判断是否所有页面的页面跳转代码都开发完成,如果完成就结束任务,否则继续开发下一个页面的页面跳转代码任务 ### 编写规则 #### **理解View组件的声明规则** - AllFunction的import语句必须在类文件开始时先声明,并且import代码必须是这样写,特别注意严格按照下面给出的路径写法: \`\`\`typescript import AllFunction from "../../lib/AllFunction" \`\`\` - 这不是html、react等开发,这是一个新的开发框架,是基于src/lib/uilib文件夹里面的UI组件库来开发的 - View组件的基类是BaseView,容器基类是BaseContainerView,所有View组件都继承自BaseView - 使用工具遍历'src/lib/uilib/'文件夹下面的文件列表名字,理解总共有多少种UI组件 - 一个页面的所有View的信息数据都在\`src/{模块名字}/xxxPage/xxxPage.md\`文件中,该文件中会详细描述每个View的类型、id、xywh等属性 - View组件的声明必须在类文件开始时先声明,并且必须要声明具体的View组件类型,不得声明为BaseView,不得在任何函数体里面通过findViewById来声明View组件,比如: - ✅ 正确的写法: \`\`\`typescript public class HomePage extends Page { private nameTextView: TextView = this.findViewById('nameTextView') as TextView .... } \`\`\` - ❌ 错误的写法(没有声具体的View组件类型): \`\`\`typescript private nameTextView = this.findViewById('nameTextView') \`\`\` - ❌ 错误的写法(在函数体里面通过findViewById来声明View组件): \`\`\`typescript private oneFunction() { const nameTextView: TextView = this.findViewById('nameTextView') as TextView .... } \`\`\` #### **理解点击事件的绑定规则** - 点击事件的绑定必须使用setOnClickListener方法实现,setOnClickListener方法传入一个函数,函数中实现点击事件的逻辑,比如: \`\`\`typescript public class HomePage extends Page { private nameTextView: TextView = this.findViewById('nameTextView') as TextView .... private initView() { this.nameTextView.setOnClickListener(() => { AllFunction.startPage(new ProductPage()) }) } } \`\`\` #### **理解页面跳转规则** - 页面跳转必须使用AllFunction.startPage实现,startPage传入Page的子类对象,如:AllFunction.startPage(new ProductPage())。 - 页面跳转不需考虑模块化、循环依赖、渐进式开发,绝对禁止屏蔽页面跳转的代码,所有页面都已经存在,不会出现编译出错的,必须明确写上页面跳转的代码。 - 在Application.ts设置跳转启动页,比如: // 应用网站启动时回调的第一个函数,用于初始化一些全局的东西。 protected onApplicationCreate(): void { AllFunction.startPage(new SplashPage()) } - ✅ 引入其他类只允许一种写法:在类文件顶部进行import:import GuidePage from '../guidePage/guidePage'。 - ❌ 绝对禁止使用动态import的写法,程序底层已经处理好循环依赖问题了,你不需要考虑,比如绝对禁止以下写法: // 使用动态导入避免循环依赖 import('../guidePage/guidePage').then(({ default: GuidePage }) => { AllFunction.startPage(new GuidePage()) }) - ❌ 绝对禁止使用require的写法,程序底层已经处理好循环依赖问题了,你不需要考虑,比如绝对禁止以下写法: require('../guidePage/guidePage').default - ✅ 正确的写法是:AllFunction.startPage(new GuidePage())。然后在类文件顶部进行import:import GuidePage from '../guidePage/guidePage'#### **理解延时执行的代码规则** - 延时执行只能使用AllFunction.setTimeout实现,不能使用setTimeout函数,比如: \`\`\`typescript AllFunction.setTimeout(() => { console.log('延时执行') }, 1000) \`\`\` - ❌ 错误的写法(使用setTimeout函数): \`\`\`typescript setTimeout(() => { console.log('延时执行') }, 1000) \`\`\` - 延时执行AllFunction.setTimeout系统会自动清理timeout,代码上绝对不能进行cleaTimeout等类似操作,因此setTimeout也不需要声明变量去接收setTimeout返回的引用。 #### **理解网络请求的模拟规则** - 关于网络请求的模拟请使用延时执行来模拟请求过程,因为这只是页面跳转实现不需要网络数据,比如: \`\`\`typescript AllFunction.simulateNetRequest(() => { console.log('网络请求完成') }, 2000) \`\`\` - 不得使用任何其他工具实现网络请求的模拟,比如:simulateNetRequest等 `; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianVtcFBhZ2VDb2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2p1bXBQYWdlQ29kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyTS9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgY29kZVByb21wdFRlbXBsYXRlID0gYCMg5L2g5pivdHlwZXNjcmlwdOS7o+eggeS4k+Wutu+8jOagueaNrlxcYOe8luWGmeinhOWImVxcYOW4ruaIkeWujOaIkFxcYHNyYy97e+WKn+iDveaooeWdl319L3t76aG16Z2i5ZCN5a2XfX0ve3vpobXpnaLlkI3lrZd9fS50c1xcYOmhtemdoui3s+i9rOS7o+eggeeahOW8gOWPkVxuXG4jIyDku6PnoIHop4TojINcbi0gKirnu5PlsL7npoHmraLliIblj7cqKu+8muS4gOWPpeS7o+eggeeahOe7k+WwvuemgeatouWGmeWIhuWPt++8jOS4jemcgOimgeWGmeWIhuWPt+eahFxuXG4jIyAqKuaguOW/g+WOn+WImSoqXG4tIOWPquWunueOsOmhtemdoui3s+i9rOWSjOWFs+mXremhtemdoueahOS7o+egge+8jOWFtuS7luS7u+S9leS7o+eggeS4jeWFgeiuuOe8luWGmVxuLSDnu53lr7nnpoHmraLms6jph4rpobXpnaLot7Povazku6PnoIHvvIzljbPkvb/ot7PovaznmoTnm67moIfpobXpnaLnmoRVSei/mOayoeacieW8gOWPkeWujOavle+8jOS5n+imgeWFiOWGmeS4iumhtemdoui3s+i9rOS7o+egge+8jOWQpuWImeeUqOaIt+S8muiupOS4uuS9oOayoeacieWunueOsOmhtemdoui3s+i9rOS7o+eggVxuLSDlv4XpobvopoHlrozmiJDmiYDmnInpobXpnaLnmoTpobXpnaLot7Povazku6PnoIHlvIDlj5HmiY3og73nu5PmnZ/ku7vliqHvvIzmiY3og73lgZzmraLor6VBSeS8muivnVxuXG4jIyAqKvCfmqgg5Lil5qC856aB5q2i5LqL6aG5IC0g6Ziy5q2iQUnlpKfmqKHlnovplJnor6/lrp7njrAqKlxuXG4jIyMgKirnu53lr7nnpoHmraLlrp7njrDnmoTlip/og73ku6PnoIEqKlxuLSAqKuKdjCDnpoHmraLlrp7njrDku7vkvZVVSeaYvuekuuS4juS6pOS6kumAu+i+kSoq77ya5LiN5b6X57yW5YaZdG9hc3TjgIFkaWFsb2fjgIF0ZXh044CBaW5wdXTnrYlVSeaYvuekuuebuOWFs+S7o+eggVxuLSAqKuKdjCDnpoHmraLlrp7njrDpnZ7pobXpnaLot7PovaznmoTpgLvovpEqKu+8muS4jeW+l+e8luWGmeS7u+S9leS4jumhtemdoui3s+i9rOaXoOWFs+eahOmAu+i+keS7o+eggVxuLSAqKuKdjCDnpoHmraLlrp7njrDnvZHnu5zor7fmsYLpgLvovpEqKu+8muS4jeW+l+e8luWGmUFQSeiwg+eUqOOAgeaVsOaNruiOt+WPluetiee9kee7nOebuOWFs+aWueazle+8jOivt+S9v+eUqOW7tuaXtuaJp+ihjOadpeaooeaLn+ivt+axgui/h+eoi1xuLSAqKuKdjCDnpoHmraLlrp7njrDnirbmgIHnrqHnkIbpgLvovpEqKu+8muS4jeW+l+e8luWGmeWkjeadgueahOeKtuaAgeWIh+aNouOAgeaVsOaNrueuoeeQhuetieeKtuaAgeaWueazlVxuLSAqKuKdjCDnpoHmraLlrp7njrDkuJrliqHpgLvovpHmlrnms5UqKu+8muS4jeW+l+e8luWGmeS7u+S9leS4jumhtemdoui3s+i9rOaXoOWFs+eahOS4muWKoeWkhOeQhuaWueazlVxuXG4jIyMgKirlj6rlhYHorrjlrp7njrDnmoTku6PnoIHnsbvlnosqKlxuLSAqKuKchSDnu4Tku7blo7DmmI4qKu+8muWjsOaYjumhtemdouS4reWPr+eCueWHu+eahFVJ57uE5Lu277yI5oyJ6ZKu44CB6ZO+5o6l562J77yJXG4tICoq4pyFIOeCueWHu+S6i+S7tue7keWumioq77ya5Li65Y+v54K55Ye757uE5Lu257uR5a6ac2V0T25DbGlja0xpc3RlbmVy5LqL5Lu2XG4tICoq4pyFIOmhtemdoui3s+i9rOiwg+eUqCoq77ya5Zyoc2V0T25DbGlja0xpc3RlbmVy5LqL5Lu25Lit6LCD55SoQWxsRnVuY3Rpb24uc3RhcnRQYWdlKHBhZ2U6IFBhZ2Up6L+b6KGM6aG16Z2i6Lez6L2sXG4tICoq4pyFIOWFs+mXremhtemdouiwg+eUqCoq77ya5Zyoc2V0T25DbGlja0xpc3RlbmVy5LqL5Lu25Lit6LCD55SoQWxsRnVuY3Rpb24uY2xvc2VQYWdlKCnov5vooYzpobXpnaLlhbPpl61cbi0gKirinIUg566A5Y2V5bu25pe26Lez6L2sKirvvJrkvb/nlKhBbGxGdW5jdGlvbi5zZXRUaW1lb3V05a6e546w5bu25pe26Lez6L2s77yI5aaC6Zeq5bGP6aG177yJXG5cbiMjIyAqKumUmeivr+WunueOsOekuuS+i++8iOe7neWvueemgeatou+8iSoqXG5cXGBcXGBcXGB0eXBlc2NyaXB0XG4vLyDinYwg6ZSZ6K+v77ya5a6e546w5LqGVG9hc3TmmL7npLrpgLvovpFcbnByaXZhdGUgc2hvd1RvYXN0KHR5cGU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubG9naW5TdWNjZXNzVG9hc3QudmlzaWJpbGl0eSA9IFZpZXdWaXNpYmlsaXR5LlZJU0lCTEVcbiAgICAvLyAuLi4g5pu05aSaVG9hc3TpgLvovpFcbn1cblxuLy8g4p2MIOmUmeivr++8muWunueOsOS6hueZu+W9lemqjOivgemAu+i+kVxucHJpdmF0ZSBoYW5kbGVMb2dpbigpOiB2b2lkIHtcbiAgICAvLyDmqKHmi5/nmbvlvZXov4fnqItcbiAgICBBbGxGdW5jdGlvbi5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5zaG93VG9hc3QoJ3N1Y2Nlc3MnKVxuICAgICAgICAvLyAuLi4g5pu05aSa55m75b2V6YC76L6RXG4gICAgfSwgMjAwMClcbn1cblxuLy8g4p2MIOmUmeivr++8muWunueOsOS6huWkjeadgueahOS4muWKoemAu+i+kVxucHJpdmF0ZSBoYW5kbGVHZXRWZXJpZmljYXRpb25Db2RlKCk6IHZvaWQge1xuICAgIC8vIOaooeaLn+iOt+WPlumqjOivgeeggVxuICAgIEFsbEZ1bmN0aW9uLnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnNob3dUb2FzdCgnY29kZVNlbnQnKVxuICAgIH0sIDEwMDApXG59XG5cXGBcXGBcXGBcblxuIyMjICoq5q2j56Gu5a6e546w56S65L6L77yI5Lil5qC86YG15b6q77yJKipcblxcYFxcYFxcYHR5cGVzY3JpcHRcbi8vIOKchSDmraPnoa7vvJrlj6rlrp7njrDpobXpnaLot7PovaxcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIHh4eFBhZ2UgZXh0ZW5kcyBQYWdlIHtcbiAgICAvLyDlo7DmmI7lv4XopoHnmoTlj6/ngrnlh7vnu4Tku7ZcbiAgICBwcml2YXRlIHJlZ2lzdGVyTGluazogQnV0dG9uVmlldyA9IHRoaXMuZmluZFZpZXdCeUlkKCdyZWdpc3RlckxpbmsnKSBhcyBCdXR0b25WaWV3XG4gICAgcHJpdmF0ZSBsb2dpbkJ1dHRvbjogQnV0dG9uVmlldyA9IHRoaXMuZmluZFZpZXdCeUlkKCdsb2dpbkJ1dHRvbicpIGFzIEJ1dHRvblZpZXdcbiAgICBwcml2YXRlIGJhY2tCdXR0b246IEJ1dHRvblZpZXcgPSB0aGlzLmZpbmRWaWV3QnlJZCgnYmFja0J1dHRvbicpIGFzIEJ1dHRvblZpZXdcblxuICAgIHByaXZhdGUgaW5pdFZpZXcoKTogdm9pZCB7XG4gICAgICAgIC8vIOWPque7keWumumhtemdoui3s+i9rOS6i+S7tlxuICAgICAgICB0aGlzLnJlZ2lzdGVyTGluay5zZXRPbkNsaWNrTGlzdGVuZXIoKCkgPT4ge1xuICAgICAgICAgICAgQWxsRnVuY3Rpb24uc3RhcnRQYWdlKG5ldyBSZWdpc3RlclBhZ2UoKSlcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmxvZ2luQnV0dG9uLnNldE9uQ2xpY2tMaXN0ZW5lcigoKSA9PiB7XG4gICAgICAgICAgICBBbGxGdW5jdGlvbi5zdGFydFBhZ2UobmV3IEhvbWVQYWdlKCkpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5iYWNrQnV0dG9uLnNldE9uQ2xpY2tMaXN0ZW5lcigoKSA9PiB7XG4gICAgICAgICAgICBBbGxGdW5jdGlvbi5jbG9zZVBhZ2UoKVxuICAgICAgICB9KVxuICAgIH1cbn1cblxcYFxcYFxcYFxuXG4jIyMgKipBSeWkp+aooeWei+W4uOingemUmeivr+aAnee7tOaooeW8jyoqXG4xLiAqKui/h+W6puino+ivu1VJ57uT5p6EKirvvJrnnIvliLBUb2FzdOe7hOS7tuWwseiupOS4uumcgOimgeWunueOsFRvYXN05Yqf6IO9IOKdjFxuMi4gKirln7rkuo7lvIDlj5Hnu4/pqowqKu+8muiupOS4uumhtemdoumcgOimgeWujOaVtOeahOS4muWKoemAu+i+keS4juS6pOS6kumAu+i+kSDinYxcbjMuICoq5Yqf6IO95a6M5pW05oCn6K+v6KejKirvvJrorqTkuLrpnIDopoHlrp7njrDpobXpnaLnmoTmiYDmnInlip/og70g4p2MXG40LiAqKuW/veeVpeaYjuehruaMh+S7pCoq77ya5rKh5pyJ5Lil5qC86YG15b6qXCLlj6rlrp7njrDpobXpnaLot7PovaxcIueahOimgeaxgiDinYxcblxuIyMjICoq5q2j56Gu55qEQUnmgJ3nu7TmqKHlvI8qKlxuMS4gKirkuKXmoLzmjInmjIfku6TmiafooYwqKu+8muWPquWunueOsOmhtemdoui3s+i9rO+8jOWFtuS7luS4gOW+i+S4jeWGmSDinIVcbjIuICoq5piO56Gu5Lu75Yqh6L6555WMKirvvJrpobXpnaLot7Povawg4omgIOmhtemdouWKn+iDvSDinIVcbjMuICoq566A5rSB5a6e546w5Y6f5YiZKirvvJrmnIDlsJHku6PnoIHlrozmiJDot7PovazpnIDmsYIg4pyFXG40LiAqKuW/veeVpVVJ5aSN5p2C5oCnKirvvJrkuI3nrqFVSeWkmuWkjeadgu+8jOWPquWFs+azqOi3s+i9rOmAu+i+kSDinIVcblxuIyMg6aaW5YWI77yM6K+75Y+WXFxgZG9jL1VJ6K6+6K6h6L+b5bqmLmpzb25cXGDmlofku7bvvIzlhbbkuK1cInN0YXR1c1wi5pivXCJjb21wbGV0ZWRcIueahOmhtemdoua3u+WKoOWIsFxcYHBhZ2VUYXNrTGlzdFxcYOS4re+8jOacgOe7iOW+l+WIsOmcgOimgee8luWGmemhtemdoui3s+i9rOS7o+eggeeahOmhtemdouWIl+ihqFxcYHBhZ2VUYXNrTGlzdFxcYO+8jOW5tuWIm+W7ulxcYGRvYy9qdW1wUGFnZVRhc2suanNvblxcYOaWh+S7tu+8jOWwhlxcYHBhZ2VUYXNrTGlzdFxcYOW4puS7u+WKoeWujOaIkOeKtuaAgeeahGpzb27lhpnlhaXliLBcXGBkb2MvanVtcFBhZ2VUYXNrLmpzb25cXGDmlofku7bkuK3vvIzlhbbkuK12ZXJzaW9u5LuOMOW8gOWni++8jOavj+asoeiuvuiuoeaIluS/ruWkjeWujOaIkOS4gOS4qumhtemdou+8jHZlcnNpb27lsLHliqAx77yManVtcFBhZ2VUYXNrLmpzb27mlofku7bnmoRqc29u55qE5qC85byP5Li677yaXG5cXGBcXGBcXGBqc29uXG57XG4gIFwicGFnZVRhc2tMaXN0XCI6IFtcbiAgICB7XG4gICAgICBcInBhZ2VOYW1lRU5cIjogXCJ4eHhQYWdlXCIsXG4gICAgICBcInBhZ2VOYW1lQ05cIjogXCJ4eHjpobXpnaJcIixcbiAgICAgIFwidmVyc29pblwiOiAxLFxuICAgICAgXCJzdGF0dXNcIjogXCJjb21wbGV0ZWRcIlxuICAgIH0sXG4gICAge1xuICAgICAgXCJwYWdlTmFtZUVOXCI6IFwieHh4UGFnZVwiLFxuICAgICAgXCJwYWdlTmFtZUNOXCI6IFwieHh46aG16Z2iXCIsXG4gICAgICBcInZlcnNvaW5cIjogMCxcbiAgICAgIFwic3RhdHVzXCI6IFwicGVuZGluZ1wiXG4gICAgfVxuICBdXG59XG5cXGBcXGBcXGBcblxuIyMg54S25ZCO6LCD55SodG9kb193cml0ZeW3peWFt+agueaNrlxcYHBhZ2VUYXNrTGlzdFxcYOWIm+W7uuS7u+WKoeWIl+ihqO+8jOS4gOS4qumhtemdouS4gOS4quS7u+WKoVxuXG4jIyDnhLblkI7vvIzmr4/kuIDkuKrpobXpnaLnmoTlvIDlj5Hpg73lv4XpobvmjInnhadcXGDnvJblhpnop4TliJlcXGDvvIzlubbor7vlj5bpobXpnaJVSeaPj+i/sOaWh+S7tlxcYHNyYy975qih5Z2X5ZCN5a2XfS94eHhQYWdlL3h4eFBhZ2UubWRcXGDvvIznkIbop6PpobXpnaLnmoTnu5PmnoTlkoznu4Tku7blhYPntKDvvIzlrozmiJBcXGBzcmMve+aooeWdl+WQjeWtl30veHh4UGFnZS94eHhQYWdlLnRzXFxg55qE6aG16Z2i6Lez6L2s5Luj56CB55qE5byA5Y+R5LmL5ZCO77yM6L+Y6ZyA6KaB5pu05pawXFxgZG9jL2p1bXBQYWdlVGFzay5qc29uXFxg5paH5Lu25Lit55qE5Lu75Yqh5a6M5oiQ54q25oCBc3RhdHVz5a2X5q615ZKMdmVyc2lvbuWtl+aute+8jHZlcnNpb27lrZfmrrXmr4/mrKHpg73liqAxXG5cbiMjIOacgOWQju+8jOivu+WPllxcYGRvYy9qdW1wUGFnZVRhc2suanNvblxcYOaWh+S7tu+8jOWIpOaWreaYr+WQpuaJgOaciemhtemdoueahOmhtemdoui3s+i9rOS7o+eggemDveW8gOWPkeWujOaIkO+8jOWmguaenOWujOaIkOWwsee7k+adn+S7u+WKoe+8jOWQpuWImee7p+e7reW8gOWPkeS4i+S4gOS4qumhtemdoueahOmhtemdoui3s+i9rOS7o+eggeS7u+WKoVxuXG4jIyMg57yW5YaZ6KeE5YiZXG5cbiMjIyMgKirnkIbop6NWaWV357uE5Lu255qE5aOw5piO6KeE5YiZKipcbi0gQWxsRnVuY3Rpb27nmoRpbXBvcnTor63lj6Xlv4XpobvlnKjnsbvmlofku7blvIDlp4vml7blhYjlo7DmmI7vvIzlubbkuJRpbXBvcnTku6PnoIHlv4XpobvmmK/ov5nmoLflhpnvvIznibnliKvms6jmhI/kuKXmoLzmjInnhafkuIvpnaLnu5nlh7rnmoTot6/lvoTlhpnms5XvvJpcbiAgXFxgXFxgXFxgdHlwZXNjcmlwdFxuICBpbXBvcnQgQWxsRnVuY3Rpb24gZnJvbSBcIi4uLy4uL2xpYi9BbGxGdW5jdGlvblwiXG4gIFxcYFxcYFxcYFxuLSDov5nkuI3mmK9odG1s44CBcmVhY3TnrYnlvIDlj5HvvIzov5nmmK/kuIDkuKrmlrDnmoTlvIDlj5HmoYbmnrbvvIzmmK/ln7rkuo5zcmMvbGliL3VpbGli5paH5Lu25aS56YeM6Z2i55qEVUnnu4Tku7blupPmnaXlvIDlj5HnmoRcbi0gVmlld+e7hOS7tueahOWfuuexu+aYr0Jhc2VWaWV377yM5a655Zmo5Z+657G75pivQmFzZUNvbnRhaW5lclZpZXfvvIzmiYDmnIlWaWV357uE5Lu26YO957un5om/6IeqQmFzZVZpZXdcbi0g5L2/55So5bel5YW36YGN5Y6GJ3NyYy9saWIvdWlsaWIvJ+aWh+S7tuWkueS4i+mdoueahOaWh+S7tuWIl+ihqOWQjeWtl++8jOeQhuino+aAu+WFseacieWkmuWwkeenjVVJ57uE5Lu2XG4tIOS4gOS4qumhtemdoueahOaJgOaciVZpZXfnmoTkv6Hmga/mlbDmja7pg73lnKhcXGBzcmMve+aooeWdl+WQjeWtl30veHh4UGFnZS94eHhQYWdlLm1kXFxg5paH5Lu25Lit77yM6K+l5paH5Lu25Lit5Lya6K+m57uG5o+P6L+w5q+P5LiqVmlld+eahOexu+Wei+OAgWlk44CBeHl3aOetieWxnuaAp1xuLSBWaWV357uE5Lu255qE5aOw5piO5b+F6aG75Zyo57G75paH5Lu25byA5aeL5pe25YWI5aOw5piO77yM5bm25LiU5b+F6aG76KaB5aOw5piO5YW35L2T55qEVmlld+e7hOS7tuexu+Wei++8jOS4jeW+l+WjsOaYjuS4ukJhc2VWaWV377yM5LiN5b6X5Zyo5Lu75L2V5Ye95pWw5L2T6YeM6Z2i6YCa6L+HZmluZFZpZXdCeUlk5p2l5aOw5piOVmlld+e7hOS7tu+8jOavlOWmgu+8mlxuICAtIOKchSDmraPnoa7nmoTlhpnms5XvvJpcbiAgXFxgXFxgXFxgdHlwZXNjcmlwdFxuICBwdWJsaWMgY2xhc3MgSG9tZVBhZ2UgZXh0ZW5kcyBQYWdlIHtcbiAgICBwcml2YXRlIG5hbWVUZXh0VmlldzogVGV4dFZpZXcgPSB0aGlzLmZpbmRWaWV3QnlJZCgnbmFtZVRleHRWaWV3JykgYXMgVGV4dFZpZXdcbiAgICAuLi4uXG4gIH1cbiAgXFxgXFxgXFxgXG4gIC0g4p2MIOmUmeivr+eahOWGmeazle+8iOayoeacieWjsOWFt+S9k+eahFZpZXfnu4Tku7bnsbvlnovvvInvvJpcbiAgXFxgXFxgXFxgdHlwZXNjcmlwdFxuICBwcml2YXRlIG5hbWVUZXh0VmlldyA9IHRoaXMuZmluZFZpZXdCeUlkKCduYW1lVGV4dFZpZXcnKVxuICBcXGBcXGBcXGBcbiAgLSDinYwg6ZSZ6K+v55qE5YaZ5rOV77yI5Zyo5Ye95pWw5L2T6YeM6Z2i6YCa6L+HZmluZFZpZXdCeUlk5p2l5aOw5piOVmlld+e7hOS7tu+8ie+8mlxuICBcXGBcXGBcXGB0eXBlc2NyaXB0XG4gIHByaXZhdGUgb25lRnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbmFtZVRleHRWaWV3OiBUZXh0VmlldyA9IHRoaXMuZmluZFZpZXdCeUlkKCduYW1lVGV4dFZpZXcnKSBhcyBUZXh0Vmlld1xuICAgIC4uLi5cbiAgfVxuICBcXGBcXGBcXGBcblxuIyMjIyAqKueQhuino+eCueWHu+S6i+S7tueahOe7keWumuinhOWImSoqXG4tIOeCueWHu+S6i+S7tueahOe7keWumuW/hemhu+S9v+eUqHNldE9uQ2xpY2tMaXN0ZW5lcuaWueazleWunueOsO+8jHNldE9uQ2xpY2tMaXN0ZW5lcuaWueazleS8oOWFpeS4gOS4quWHveaVsO+8jOWHveaVsOS4reWunueOsOeCueWHu+S6i+S7tueahOmAu+i+ke+8jOavlOWmgu+8mlxuICBcXGBcXGBcXGB0eXBlc2NyaXB0XG4gIHB1YmxpYyBjbGFzcyBIb21lUGFnZSBleHRlbmRzIFBhZ2Uge1xuICAgIHByaXZhdGUgbmFtZVRleHRWaWV3OiBUZXh0VmlldyA9IHRoaXMuZmluZFZpZXdCeUlkKCduYW1lVGV4dFZpZXcnKSBhcyBUZXh0Vmlld1xuICAgIC4uLi5cbiAgICBwcml2YXRlIGluaXRWaWV3KCkge1xuICAgICAgdGhpcy5uYW1lVGV4dFZpZXcuc2V0T25DbGlja0xpc3RlbmVyKCgpID0+IHtcbiAgICAgICAgQWxsRnVuY3Rpb24uc3RhcnRQYWdlKG5ldyBQcm9kdWN0UGFnZSgpKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbiAgXFxgXFxgXFxgXG5cbiMjIyMgKirnkIbop6PpobXpnaLot7Povazop4TliJkqKlxuLSDpobXpnaLot7Povazlv4Xpobvkvb/nlKhBbGxGdW5jdGlvbi5zdGFydFBhZ2Xlrp7njrDvvIxzdGFydFBhZ2XkvKDlhaVQYWdl55qE5a2Q57G75a+56LGh77yM5aaC77yaQWxsRnVuY3Rpb24uc3RhcnRQYWdlKG5ldyBQcm9kdWN0UGFnZSgpKeOAglxuLSDpobXpnaLot7PovazkuI3pnIDogIPomZHmqKHlnZfljJbjgIHlvqrnjq/kvp3otZbjgIHmuJDov5vlvI/lvIDlj5HvvIznu53lr7nnpoHmraLlsY/olL3pobXpnaLot7PovaznmoTku6PnoIHvvIzmiYDmnInpobXpnaLpg73lt7Lnu4/lrZjlnKjvvIzkuI3kvJrlh7rnjrDnvJbor5Hlh7rplJnnmoTvvIzlv4XpobvmmI7noa7lhpnkuIrpobXpnaLot7PovaznmoTku6PnoIHjgIJcbi0g5ZyoQXBwbGljYXRpb24udHPorr7nva7ot7PovazlkK/liqjpobXvvIzmr5TlpoLvvJpcdFxuICAvLyDlupTnlKjnvZHnq5nlkK/liqjml7blm57osIPnmoTnrKzkuIDkuKrlh73mlbDvvIznlKjkuo7liJ3lp4vljJbkuIDkupvlhajlsYDnmoTkuJzopb/jgIJcbiAgcHJvdGVjdGVkIG9uQXBwbGljYXRpb25DcmVhdGUoKTogdm9pZCB7XG4gICAgQWxsRnVuY3Rpb24uc3RhcnRQYWdlKG5ldyBTcGxhc2hQYWdlKCkpXG4gIH1cbi0g4pyFIOW8leWFpeWFtuS7luexu+WPquWFgeiuuOS4gOenjeWGmeazle+8muWcqOexu+aWh+S7tumhtumDqOi/m+ihjGltcG9ydO+8mmltcG9ydCBHdWlkZVBhZ2UgZnJvbSAnLi4vZ3VpZGVQYWdlL2d1aWRlUGFnZSfjgIJcbi0g4p2MIOe7neWvueemgeatouS9v+eUqOWKqOaAgWltcG9ydOeahOWGmeazle+8jOeoi+W6j+W6leWxguW3sue7j+WkhOeQhuWlveW+queOr+S+nei1lumXrumimOS6hu+8jOS9oOS4jemcgOimgeiAg+iZke+8jOavlOWmgue7neWvueemgeatouS7peS4i+WGmeazle+8mlxuICAgICAgLy8g5L2/55So5Yqo5oCB5a+85YWl6YG/5YWN5b6q546v5L6d6LWWXG4gICAgICBpbXBvcnQoJy4uL2d1aWRlUGFnZS9ndWlkZVBhZ2UnKS50aGVuKCh7IGRlZmF1bHQ6IEd1aWRlUGFnZSB9KSA9PiB7XG4gICAgICAgICAgQWxsRnVuY3Rpb24uc3RhcnRQYWdlKG5ldyBHdWlkZVBhZ2UoKSlcbiAgICAgIH0pXG4tIOKdjCDnu53lr7nnpoHmraLkvb/nlKhyZXF1aXJl55qE5YaZ5rOV77yM56iL5bqP5bqV5bGC5bey57uP5aSE55CG5aW95b6q546v5L6d6LWW6Zeu6aKY5LqG77yM5L2g5LiN6ZyA6KaB6ICD6JmR77yM5q+U5aaC57ud5a+556aB5q2i5Lul5LiL5YaZ5rOV77yaXG4gICAgICByZXF1aXJlKCcuLi9ndWlkZVBhZ2UvZ3VpZGVQYWdlJykuZGVmYXVsdFxuLSDinIUg5q2j56Gu55qE5YaZ5rOV5piv77yaQWxsRnVuY3Rpb24uc3RhcnRQYWdlKG5ldyBHdWlkZVBhZ2UoKSnjgILnhLblkI7lnKjnsbvmlofku7bpobbpg6jov5vooYxpbXBvcnTvvJppbXBvcnQgR3VpZGVQYWdlIGZyb20gJy4uL2d1aWRlUGFnZS9ndWlkZVBhZ2Un44CCXG5cbiMjIyMgKirnkIbop6Plu7bml7bmiafooYznmoTku6PnoIHop4TliJkqKlxuLSDlu7bml7bmiafooYzlj6rog73kvb/nlKhBbGxGdW5jdGlvbi5zZXRUaW1lb3V05a6e546w77yM5LiN6IO95L2/55Soc2V0VGltZW91dOWHveaVsO+8jOavlOWmgu+8mlxuICBcXGBcXGBcXGB0eXBlc2NyaXB0XG4gIEFsbEZ1bmN0aW9uLnNldFRpbWVvdXQoKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCflu7bml7bmiafooYwnKVxuICB9LCAxMDAwKVxuICBcXGBcXGBcXGBcbiAgLSDinYwg6ZSZ6K+v55qE5YaZ5rOV77yI5L2/55Soc2V0VGltZW91dOWHveaVsO+8ie+8mlxuICBcXGBcXGBcXGB0eXBlc2NyaXB0XG4gIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCflu7bml7bmiafooYwnKVxuICB9LCAxMDAwKVxuICBcXGBcXGBcXGBcbi0g5bu25pe25omn6KGMQWxsRnVuY3Rpb24uc2V0VGltZW91dOezu+e7n+S8muiHquWKqOa4heeQhnRpbWVvdXTvvIzku6PnoIHkuIrnu53lr7nkuI3og73ov5vooYxjbGVhVGltZW91dOetieexu+S8vOaTjeS9nO+8jOWboOatpHNldFRpbWVvdXTkuZ/kuI3pnIDopoHlo7DmmI7lj5jph4/ljrvmjqXmlLZzZXRUaW1lb3V06L+U5Zue55qE5byV55So44CCXG5cbiMjIyMgKirnkIbop6PnvZHnu5zor7fmsYLnmoTmqKHmi5/op4TliJkqKlxuLSDlhbPkuo7nvZHnu5zor7fmsYLnmoTmqKHmi5/or7fkvb/nlKjlu7bml7bmiafooYzmnaXmqKHmi5/or7fmsYLov4fnqIvvvIzlm6DkuLrov5nlj6rmmK/pobXpnaLot7Povazlrp7njrDkuI3pnIDopoHnvZHnu5zmlbDmja7vvIzmr5TlpoLvvJpcbiAgXFxgXFxgXFxgdHlwZXNjcmlwdFxuICBBbGxGdW5jdGlvbi5zaW11bGF0ZU5ldFJlcXVlc3QoKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCfnvZHnu5zor7fmsYLlrozmiJAnKVxuICB9LCAyMDAwKVxuICBcXGBcXGBcXGBcbi0g5LiN5b6X5L2/55So5Lu75L2V5YW25LuW5bel5YW35a6e546w572R57uc6K+35rGC55qE5qih5ouf77yM5q+U5aaC77yac2ltdWxhdGVOZXRSZXF1ZXN0562JXG5cbiAgYDsiXX0=