韵律之趣 發表於 2019-8-15 08:53:00

React Native 混合开发与实现

<div class="markdown-here-wrapper" data-md-url="https://i.cnblogs.com/EditPosts.aspx?postid=11335948&amp;update=1">
<h2 id="-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.4em; border-bottom: 1px solid rgba(238, 238, 238, 1)">关于</h2>
<ul style="margin: 1.2em 0; padding-left: 2em">
<li style="margin: 0.5em 0; font-size: 14px">微信公众号:前端呼啦圈(Love-FED)</li>
<li style="margin: 0.5em 0; font-size: 14px">我的博客:劳卜的博客</li>
<li style="margin: 0.5em 0; font-size: 14px">知乎专栏:前端呼啦圈</li>
</ul>
<h2 id="-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.4em; border-bottom: 1px solid rgba(238, 238, 238, 1)">前言</h2>
<p style="font-size: 14px; margin: 0 0 1.2em !important">随着 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">React</code> 的盛行,其移动开发框架 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">React Native</code> 也收到了广大开发者的青睐,以下简称 RN。通过 RN 我们能够使用 JavaScript 语言来实现跨平台移动应用的开发,打开了前端工程师通往移动平台的大门。用 RN 官方的介绍来概括它的特点就是:<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">Learn once, write anywhere</code>。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">如果你了解 React,那么学习 RN 的话应该会非常轻松。因为 RN 和 React 使用了相同的开发语言 JavaScript 和相同的设计理念 React,在 React 的基础上添加了原生平台的底层支持。这样,不同平台的适配就交由 RN 去处理,而开发者只需要关注 RN 平台应用开发本身。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">本文将从 RN 混合开发(与 iOS、Android 平台交互)的原理和实现进行介绍,结合流程图的方式让大家进一步的了解 RN 开发的思想和底层逻辑。</p>
<h2 id="-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.4em; border-bottom: 1px solid rgba(238, 238, 238, 1)">原理与实现</h2>
<h3 id="1-hello-world-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">1. 从 Hello world 开始</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">先来看一个使用 RN 实现的简单的 Hello world 展示:</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183611912-787853985.jpg" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">上方我们不难看到一些很熟悉的 React 语法,但除此之外我们还能看到其引入了 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">react-native</code> 库中的 AppRegistry API 和 Text (文本)组件,这便是 RN 提供给我们用于调用原生平台的 APIs 和 组件,其能够在不同移动设备上实现一致的功能和逻辑。最后展示在 APP 中的便是 Hello world 文本,而至于 AppRegistry API 后面会做相应介绍。</p>
<h3 id="2-react-native-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">2. 解刨 React Native 应用的结构</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">那么看完 Hello world 示例后,我们应该大致知道了 RN 应用的一个结构,我们用图例的方式进行解刨说明,如下图所示:</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183636887-1167159897.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">从图中可以看到,我们整个的 RN 应用可以分为两层展示:</p>
<ul style="margin: 1.2em 0; padding-left: 2em">
<li style="margin: 0.5em 0; font-size: 14px">JavaScript Code 层</li>
<li style="margin: 0.5em 0; font-size: 14px">Native Code 层</li>
</ul>
<p style="font-size: 14px; margin: 0 0 1.2em !important">也可以理解为所谓的应用层和底层。应用层通过 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">JavaScript 桥接层</code> 与底层平台进行交互,获取底层平台的原生 APIs、UI 组件及一些自定义组件等。比如 Hello world 示例中引入的 AppRegistry API 和 Text 组件便是很好的说明。<br>这样的分层能够使应用层的开发变得简单、高效和跨平台,对于应用的稳定性、运行时的性能来说将和原生平台保持接近。</p>
<h3 id="3-react-native-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">3. 原生平台调用 React Native 组件</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">大致了解完 React Native 应用的结构后,我们不妨再来认识下原生平台是如何调用 React Native 组件的。我们 RN 的代码要跑在原生 APP 中那必然需要原生 APP 加载运行对应的 RN 组件,以实现混合开发和交互的功能。这里就要来介绍下刚刚搁置的 AppRegistry API 了。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183719406-1031032277.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">一般我们的 RN 项目都会有一个入口文件,比如 index.js(老版本会存在两个:index.ios.js 和 index.android.js)用于注册根组件并提供给原生平台运行。这里的注册根组件就要通过 AppRegistry API 来实现。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><br>我们需要在根组件里调用 AppRegistry 中的 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">registerComponent</code> 方法进行组件的注册。注册完之后原生平台便可以通过 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">runApplication</code> 方法来运行注册过的根组件。需要注意的是注册和运行的组件名称两者必须保持一致,这样才能够实现加载对应的组件。比如 Hello world 示例中我们注册的根组件名为 HelloWorldApp,并且注入相应的组件模块。另外同时一个入口文件中,我们也可以注册多个根组件。</p>
<h3 id="4-react-native-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">4. 原生加载 React Native 界面</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">刚刚在介绍原生平台调用 RN 组件时提到了加载对应根组件的功能。那么是不是原生平台只有通过不断的调用运行 RN 注册的根组件才能实现不同页面的首次加载呢(这里的加载指原生打开 RN 页面)?答案是否定的。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183732389-156585251.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">除了上述通过调用不同的根组件来实现原生打开不同的 RN 界面外(图中第二点),我们还可以调用一个根组件来实现。唯一的区别在于我们需要调用时在 initialProperties 中添加区分不同界面的标识位来渲染不同的组件,就好比在 URL 上携带不同参数跳转到同一路由一样,根据路由上的参数在应用层进行对应组件的渲染。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">在 RN 根组件中我们可以通过 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">this.props</code> 获取原生平台携带过来的参数对象,如示例中的 viewName,再根据 viewName 实现 RN 内部组件的渲染,当然也可以结合 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">react-navigation</code> 来实现路由模块的切换。至于最终选择哪种方式加载,决定权还是要看业务的划分和功能的定义。相比较而言第一种可能更加灵活和便捷。</p>
<h3 id="5-react-native-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">5. React Native 与原生平台通信原理</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">在混合开发模式下,我们不可避免的需要和原生平台进行数据的通信,那么在 RN 中,我们如何与原生平台进行通信呢?如何获取原生平台提供的数据或将数据传递给原生平台呢?下面这张图便介绍了这一流程。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183744665-763357085.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">在 RN 中,我们可以引用 react-native 模块中的 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">NativeModules</code> API 来进行数据通信,调用的方法是 NativeModules.模块名称.接口名称,而原生平台返回数据到 RN 平台是基于回调,代码如下:</p>
<pre><code class="hljs language-javascript" style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0.5em; border: 1px solid rgba(204, 204, 204, 1); background: rgba(248, 248, 248, 1); border-radius: 3px; display: block; white-space: pre; overflow: auto; overflow-x: auto; color: rgba(51, 51, 51, 1); text-size-adjust: none">import { NativeModules } from <span class="hljs-string" style="color: rgba(221, 17, 68, 1)">'react-native'</span>;
<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold">const</span> userInfo = NativeModules.UserInfo; <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic">// 获取自定义用户信息模块</span>
<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1)">console</span>.log(userInfo.userName); <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic">// 打印用户名</span>
<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold">const</span> router = NativeModules.Router; <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic">// 获取自定义路由模块</span>
<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic">// 调用原生路由跳转方法</span>
router.openHome(<span class="hljs-string" style="color: rgba(221, 17, 68, 1)">'参数'</span>, (res) =&gt; {
    <span class="hljs-built_in" style="color: rgba(0, 134, 179, 1)">console</span>.log(res); <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic">// 打印返回数据</span>
});
</code></pre>
<p style="font-size: 14px; margin: 0 0 1.2em !important">通过 NativeModules 我们可以灵活的获取或传递数据给原生平台,同时我们也可以根据业务需要编写不同的 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">Bridge</code> 方法来实现数据通信模块的封装,比如用户信息模块、路由跳转模块及网络请求模块等。</p>
<h3 id="6-redux-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">6. Redux 架构</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">在 RN 项目中,除了与原生平台通信和交互的功能外,RN 平台自身也需要实现一些数据状态的管理。这里我们还得认识下 Redux 架构。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">&nbsp;</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811193611867-1708510242.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">&nbsp;</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">Redux 是一个用于管理 React 应用状态的容器,在 RN 中也同样适用。其采用单一数据流的方式来实现数据的管理,唯一改变 state 的方法是提交 action 操作。这样的架构使得我们的 RN 项目数据易于维护或扩容,改变数据的流程容易追踪和捕获。需要了解的具体关键字如下:</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">&nbsp;</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183806290-1788696971.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">具体文档可以参考:http://cn.redux.js.org/<br>当然你也可以使用其他第三方库实现类似的架构,比如 mobx、dva 等。</p>
<h3 id="7-css-in-js" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">7. CSS-in-JS</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">除了 Redux 架构,RN 中还加入了 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">CSS in JS</code> 的概念,将原本关注点分离的理念转移到了关注点混合上,使得我们可以在 JS 中写 CSS 代码,但这并不违背之前关注点分离的理念。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183817614-2125565518.png" alt=""></p>
<blockquote style="margin: 1.2em 0; border-left: 4px solid rgba(221, 221, 221, 1); padding: 0 1em; color: rgba(119, 119, 119, 1); quotes: none">
<p style="font-size: 14px; margin: 0 0 1.2em !important">现在随着组件化概念的流行,对从组件层面维护 CSS 样式的需求日益增大,CSS-in-JS 就是在组件内部使用 JavaScript 对 CSS 进行了抽象,可以对其声明和加以维护。这样不仅降低了编写 CSS 样式带来的风险,也让开发变得更加轻松。它和 CSS Modules 的区别是不再需要 CSS 样式文件。</p>





</blockquote>
<p style="font-size: 14px; margin: 0 0 1.2em !important">结合 JSX 语法,在 RN 中书写和维护 CSS 变得更加便捷,也是 Web 组件化不断发展的必然产物。</p>
<h3 id="8-react-native-flex-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">8. React Native 中 的 Flex 布局</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">另外,在开发 RN 项目时,官方推荐使用的布局方式是 <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; border: 1px solid rgba(234, 234, 234, 1); background-color: rgba(248, 248, 248, 1); border-radius: 3px; display: inline; white-space: nowrap !important">Flex</code> 布局,因为 Flexbox 可以在不同屏幕尺寸上提供一致的布局结构,这也解决了跨平台布局呈现的问题。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183827635-404226368.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">相比我们客户端使用的 Flex 布局,RN 中的 Flex 布局有稍许的不同,比如 flexDirection 的默认值是 column 而不是 row,flex 也只能指定一个数字值等。关于 Flex 布局的介绍可以参考:Flex 布局教程:语法篇、Flex 布局教程:实例篇</p>
<h3 id="9-react-native-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.3em">9. React Native 的热部署</h3>
<p style="font-size: 14px; margin: 0 0 1.2em !important">最后我们介绍下 RN 中的热部署,这也是选择 RN 开发 APP 的一个重要原因之一。相比传统 APP 更新,大都需要第三方审核的流程,而这个流程可能会很慢或者不及时,遇到需要紧急修复的 bug 无法及时更新而导致直接的经济损失是很常见的问题,而 RN 的热部署可以一定程度上解决或减轻这一问题的影响。那么其实现原理是怎样的呢?</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183838915-821439535.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">上图左侧部分便展现了用户访问 RN 应用的热部署流程。首先用户访问 APP,APP 会向 RN 服务器请求资源包,如果资源包未更新则读取本地缓存资源,如果开发者为了解决 bug 重新更新了服务器上的资源包,那么 APP 拉去后会缓存起来,待用户下次进入后再进行更新。这便是 RN 热部署的流程。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">在本地开发时,我们不难发现当我们在运行起来的 RN 项目中修改代码时,再次从 APP 进入 RN 页面,本地终端会再次加载一次更新后的资源数据,这也是 RN 热部署的体现。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">同样线上的热部署则需要将我们打包后的 RN 资源上传到服务器上供 APP 读取来实现。</p>
<p style="font-size: 14px; margin: 0 0 1.2em !important"><img src="https://img2018.cnblogs.com/blog/775838/201908/775838-20190811183423157-364219162.png" alt=""></p>
<p style="font-size: 14px; margin: 0 0 1.2em !important">我们可以手动执行打包、上传发布流程,当然为了减少人为干预,实现前端自动化,我们也可以把这块流程交给构建平台去自动打包部署,这便需要搭建一个后台系统进行管理。</p>
<h2 id="-" style="margin: 1.3em 0 1em; padding: 0; font-weight: bold; font-size: 1.4em; border-bottom: 1px solid rgba(238, 238, 238, 1)">结语</h2>
<p style="font-size: 14px; margin: 0 0 1.2em !important">本文介绍了 React Native 混合开发的原理与实现逻辑。只有先了解原理,才能高效的投入项目的开发中,而关于 RN 自身的功能实现大家可以直接阅读官方文档,这里我也额外提供一些关于 RN 的参考资料:</p>
<ul style="margin: 1.2em 0; padding-left: 2em">
<li style="margin: 0.5em 0; font-size: 14px">React-Native学习指南</li>
<li style="margin: 0.5em 0; font-size: 14px">分享 50 个完整的 React Native 项目</li>
<li style="margin: 0.5em 0; font-size: 14px">给所有开发者的React Native详细入门指南</li>
<li style="margin: 0.5em 0; font-size: 14px">30天学习React Native教程</li>





</ul>
<p style="font-size: 14px; margin: 0 0 1.2em !important">注:本文部分图例参考自《React Native 移动开发实战》一书</p>
<div style="height: 0; width: 0; max-height: 0; max-width: 0; overflow: hidden; font-size: 0; padding: 0; margin: 0" title="MDH:PHA+IyMg5YWz5LqOPGJyPiog5b6u5L+h5YWs5LyX5Y+377ya5YmN56uv5ZG85ZWm5ZyI77yITG92
ZS1GRUTvvIk8YnI+KiDmiJHnmoTljZrlrqLvvJpb5Yqz5Y2c55qE5Y2a5a6iXShodHRwOi8vd3d3
LmNuYmxvZ3MuY29tL2x1b3poaWhhbyk8YnI+KiDnn6XkuY7kuJPmoI/vvJpb5YmN56uv5ZG85ZWm
5ZyIXShodHRwczovL3podWFubGFuLnpoaWh1LmNvbS9mb250LWVuZCk8L3A+PHA+Jm5ic3A7PC9w
PjxwPiMjIOWJjeiogDxicj7pmo/nnYAgYFJlYWN0YCDnmoTnm5vooYzvvIzlhbbnp7vliqjlvIDl
j5HmoYbmnrYgYFJlYWN0IE5hdGl2ZWAg5Lmf5pS25Yiw5LqG5bm/5aSn5byA5Y+R6ICF55qE6Z2S
552Q77yM5Lul5LiL566A56ewIFJO44CC6YCa6L+HIFJOIOaIkeS7rOiDveWkn+S9v+eUqCBKYXZh
U2NyaXB0IOivreiogOadpeWunueOsOi3qOW5s+WPsOenu+WKqOW6lOeUqOeahOW8gOWPke+8jOaJ
k+W8gOS6huWJjeerr+W3peeoi+W4iOmAmuW+gOenu+WKqOW5s+WPsOeahOWkp+mXqOOAgueUqCBS
TiDlrpjmlrnnmoTku4vnu43mnaXmpoLmi6zlroPnmoTnibnngrnlsLHmmK/vvJpgTGVhcm4gb25j
ZSwgd3JpdGUgYW55d2hlcmVg44CCPC9wPjxwPiZuYnNwOzwvcD48cD7lpoLmnpzkvaDkuobop6Mg
UmVhY3TvvIzpgqPkuYjlrabkuaAgUk4g55qE6K+d5bqU6K+l5Lya6Z2e5bi46L275p2+44CC5Zug
5Li6IFJOIOWSjCBSZWFjdCDkvb/nlKjkuobnm7jlkIznmoTlvIDlj5Hor63oqIAgSmF2YVNjcmlw
dCDlkoznm7jlkIznmoTorr7orqHnkIblv7UgUmVhY3TvvIzlnKggUmVhY3Qg55qE5Z+656GA5LiK
5re75Yqg5LqG5Y6f55Sf5bmz5Y+w55qE5bqV5bGC5pSv5oyB44CC6L+Z5qC377yM5LiN5ZCM5bmz
5Y+w55qE6YCC6YWN5bCx5Lqk55SxIFJOIOWOu+WkhOeQhu+8jOiAjOW8gOWPkeiAheWPqumcgOim
geWFs+azqCBSTiDlubPlj7DlupTnlKjlvIDlj5HmnKzouqvjgII8L3A+PHA+Jm5ic3A7PC9wPjxw
PuacrOaWh+WwhuS7jiBSTiDmt7flkIjlvIDlj5HvvIjkuI4gaU9T44CBQW5kcm9pZCDlubPlj7Dk
uqTkupLvvInnmoTljp/nkIblkozlrp7njrDov5vooYzku4vnu43vvIznu5PlkIjmtYHnqIvlm77n
moTmlrnlvI/orqnlpKflrrbov5vkuIDmraXnmoTkuobop6MgUk4g5byA5Y+R55qE5oCd5oOz5ZKM
5bqV5bGC6YC76L6R44CCPC9wPjxwPiZuYnNwOzwvcD48cD4jIyDljp/nkIbkuI7lrp7njrA8L3A+
PHA+IyMjIDEuIOS7jiBIZWxsbyB3b3JsZCDlvIDlp4s8L3A+PHA+5YWI5p2l55yL5LiA5Liq5L2/
55SoIFJOIOWunueOsOeahOeugOWNleeahCBIZWxsbyB3b3JsZCDlsZXnpLrvvJo8L3A+PHA+Jm5i
c3A7PC9wPjxwPjxpbWcgc3JjPSJodHRwczovL2ltZzIwMTguY25ibG9ncy5jb20vYmxvZy83NzU4
MzgvMjAxOTA4Lzc3NTgzOC0yMDE5MDgxMTE4MzYxMTkxMi03ODc4NTM5ODUuanBnIiBhbHQ9IiIg
ZGF0YS1tY2Utc3JjPSJodHRwczovL2ltZzIwMTguY25ibG9ncy5jb20vYmxvZy83NzU4MzgvMjAx
OTA4Lzc3NTgzOC0yMDE5MDgxMTE4MzYxMTkxMi03ODc4NTM5ODUuanBnIj48L3A+PHA+Jm5ic3A7
PC9wPjxwPuS4iuaWueaIkeS7rOS4jemavueci+WIsOS4gOS6m+W+iOeGn+aCieeahCBSZWFjdCDo
r63ms5XvvIzkvYbpmaTmraTkuYvlpJbmiJHku6zov5jog73nnIvliLDlhbblvJXlhaXkuoYgYHJl
YWN0LW5hdGl2ZWAg5bqT5Lit55qEIEFwcFJlZ2lzdHJ5IEFQSSDlkowgVGV4dCAo5paH5pysKee7
hOS7tu+8jOi/meS+v+aYryBSTiDmj5Dkvpvnu5nmiJHku6znlKjkuo7osIPnlKjljp/nlJ/lubPl
j7DnmoQgQVBJcyDlkowg57uE5Lu277yM5YW26IO95aSf5Zyo5LiN5ZCM56e75Yqo6K6+5aSH5LiK
5a6e546w5LiA6Ie055qE5Yqf6IO95ZKM6YC76L6R44CC5pyA5ZCO5bGV56S65ZyoIEFQUCDkuK3n
moTkvr/mmK8gSGVsbG8gd29ybGQg5paH5pys77yM6ICM6Iez5LqOIEFwcFJlZ2lzdHJ5IEFQSSDl
kI7pnaLkvJrlgZrnm7jlupTku4vnu43jgII8L3A+PHA+Jm5ic3A7PC9wPjxwPiMjIyAyLiDop6Pl
iKggUmVhY3QgTmF0aXZlIOW6lOeUqOeahOe7k+aehDwvcD48cD7pgqPkuYjnnIvlrowgSGVsbG8g
d29ybGQg56S65L6L5ZCO77yM5oiR5Lus5bqU6K+l5aSn6Ie055+l6YGT5LqGIFJOIOW6lOeUqOea
hOS4gOS4que7k+aehO+8jOaIkeS7rOeUqOWbvuS+i+eahOaWueW8j+i/m+ihjOino+WIqOivtOaY
ju+8jOWmguS4i+WbvuaJgOekuu+8mjwvcD48cD4mbmJzcDs8L3A+PHA+PGltZyBzcmM9Imh0dHBz
Oi8vaW1nMjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4LTIwMTkwODEx
MTgzNjM2ODg3LTExNjcxNTk4OTcucG5nIiBhbHQ9IiIgZGF0YS1tY2Utc3JjPSJodHRwczovL2lt
ZzIwMTguY25ibG9ncy5jb20vYmxvZy83NzU4MzgvMjAxOTA4Lzc3NTgzOC0yMDE5MDgxMTE4MzYz
Njg4Ny0xMTY3MTU5ODk3LnBuZyI+PC9wPjxwPiZuYnNwOzwvcD48cD7ku47lm77kuK3lj6/ku6Xn
nIvliLDvvIzmiJHku6zmlbTkuKrnmoQgUk4g5bqU55So5Y+v5Lul5YiG5Li65Lik5bGC5bGV56S6
77yaPGJyPiogSmF2YVNjcmlwdCBDb2RlIOWxgiA8YnI+KiBOYXRpdmUgQ29kZSDlsYI8L3A+PHA+
Jm5ic3A7PC9wPjxwPuS5n+WPr+S7peeQhuino+S4uuaJgOiwk+eahOW6lOeUqOWxguWSjOW6leWx
guOAguW6lOeUqOWxgumAmui/hyBgSmF2YVNjcmlwdCDmoaXmjqXlsYJgIOS4juW6leWxguW5s+WP
sOi/m+ihjOS6pOS6ku+8jOiOt+WPluW6leWxguW5s+WPsOeahOWOn+eUnyBBUElz44CBVUkg57uE
5Lu25Y+K5LiA5Lqb6Ieq5a6a5LmJ57uE5Lu2562J44CC5q+U5aaCIEhlbGxvIHdvcmxkIOekuuS+
i+S4reW8leWFpeeahCBBcHBSZWdpc3RyeSBBUEkg5ZKMIFRleHQg57uE5Lu25L6/5piv5b6I5aW9
55qE6K+05piO44CCPC9wPjxwPui/meagt+eahOWIhuWxguiDveWkn+S9v+W6lOeUqOWxgueahOW8
gOWPkeWPmOW+l+eugOWNleOAgemrmOaViOWSjOi3qOW5s+WPsO+8jOWvueS6juW6lOeUqOeahOeo
s+WumuaAp+OAgei/kOihjOaXtueahOaAp+iDveadpeivtOWwhuWSjOWOn+eUn+W5s+WPsOS/neaM
geaOpei/keOAgjwvcD48cD4mbmJzcDs8L3A+PHA+IyMjIDMuIOWOn+eUn+W5s+WPsOiwg+eUqCBS
ZWFjdCBOYXRpdmUg57uE5Lu2PC9wPjxwPuWkp+iHtOS6huino+WujCBSZWFjdCBOYXRpdmUg5bqU
55So55qE57uT5p6E5ZCO77yM5oiR5Lus5LiN5aao5YaN5p2l6K6k6K+G5LiL5Y6f55Sf5bmz5Y+w
5piv5aaC5L2V6LCD55SoIFJlYWN0IE5hdGl2ZSDnu4Tku7bnmoTjgILmiJHku6wgUk4g55qE5Luj
56CB6KaB6LeR5Zyo5Y6f55SfIEFQUCDkuK3pgqPlv4XnhLbpnIDopoHljp/nlJ8gQVBQIOWKoOi9
vei/kOihjOWvueW6lOeahCBSTiDnu4Tku7bvvIzku6Xlrp7njrDmt7flkIjlvIDlj5HlkozkuqTk
upLnmoTlip/og73jgILov5nph4zlsLHopoHmnaXku4vnu43kuIvliJrliJrmkIHnva7nmoQgQXBw
UmVnaXN0cnkgQVBJIOS6huOAgjwvcD48cD4mbmJzcDs8L3A+PHA+PGltZyBzcmM9Imh0dHBzOi8v
aW1nMjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4LTIwMTkwODExMTgz
NzE5NDA2LTEwMzEwMzIyNzcucG5nIiBhbHQ9IiIgZGF0YS1tY2Utc3JjPSJodHRwczovL2ltZzIw
MTguY25ibG9ncy5jb20vYmxvZy83NzU4MzgvMjAxOTA4Lzc3NTgzOC0yMDE5MDgxMTE4MzcxOTQw
Ni0xMDMxMDMyMjc3LnBuZyI+PC9wPjxwPiZuYnNwOzwvcD48cD7kuIDoiKzmiJHku6znmoQgUk4g
6aG555uu6YO95Lya5pyJ5LiA5Liq5YWl5Y+j5paH5Lu277yM5q+U5aaCIGluZGV4Lmpz77yI6ICB
54mI5pys5Lya5a2Y5Zyo5Lik5Liq77yaaW5kZXguaW9zLmpzIOWSjCBpbmRleC5hbmRyb2lkLmpz
77yJ55So5LqO5rOo5YaM5qC557uE5Lu25bm25o+Q5L6b57uZ5Y6f55Sf5bmz5Y+w6L+Q6KGM44CC
6L+Z6YeM55qE5rOo5YaM5qC557uE5Lu25bCx6KaB6YCa6L+HIEFwcFJlZ2lzdHJ5IEFQSSDmnaXl
rp7njrDjgII8L3A+PHA+5oiR5Lus6ZyA6KaB5Zyo5qC557uE5Lu26YeM6LCD55SoIEFwcFJlZ2lz
dHJ5IOS4reeahCBgcmVnaXN0ZXJDb21wb25lbnRgIOaWueazlei/m+ihjOe7hOS7tueahOazqOWG
jOOAguazqOWGjOWujOS5i+WQjuWOn+eUn+W5s+WPsOS+v+WPr+S7pemAmui/hyBgcnVuQXBwbGlj
YXRpb25gIOaWueazleadpei/kOihjOazqOWGjOi/h+eahOaguee7hOS7tuOAgumcgOimgeazqOaE
j+eahOaYr+azqOWGjOWSjOi/kOihjOeahOe7hOS7tuWQjeensOS4pOiAheW/hemhu+S/neaMgeS4
gOiHtO+8jOi/meagt+aJjeiDveWkn+WunueOsOWKoOi9veWvueW6lOeahOe7hOS7tuOAguavlOWm
giBIZWxsbyB3b3JsZCDnpLrkvovkuK3miJHku6zms6jlhoznmoTmoLnnu4Tku7blkI3kuLogSGVs
bG9Xb3JsZEFwcO+8jOW5tuS4lOazqOWFpeebuOW6lOeahOe7hOS7tuaooeWdl+OAguWPpuWkluWQ
jOaXtuS4gOS4quWFpeWPo+aWh+S7tuS4re+8jOaIkeS7rOS5n+WPr+S7peazqOWGjOWkmuS4quag
uee7hOS7tuOAgjwvcD48cD4mbmJzcDs8L3A+PHA+IyMjIDQuIOWOn+eUn+WKoOi9vSBSZWFjdCBO
YXRpdmUg55WM6Z2iPC9wPjxwPuWImuWImuWcqOS7i+e7jeWOn+eUn+W5s+WPsOiwg+eUqCBSTiDn
u4Tku7bml7bmj5DliLDkuobliqDovb3lr7nlupTmoLnnu4Tku7bnmoTlip/og73jgILpgqPkuYjm
mK/kuI3mmK/ljp/nlJ/lubPlj7Dlj6rmnInpgJrov4fkuI3mlq3nmoTosIPnlKjov5DooYwgUk4g
5rOo5YaM55qE5qC557uE5Lu25omN6IO95a6e546w5LiN5ZCM6aG16Z2i55qE6aaW5qyh5Yqg6L29
5ZGi77yI6L+Z6YeM55qE5Yqg6L295oyH5Y6f55Sf5omT5byAIFJOIOmhtemdou+8ie+8n+etlOah
iOaYr+WQpuWumueahOOAgjwvcD48cD4mbmJzcDs8L3A+PHA+PGltZyBzcmM9Imh0dHBzOi8vaW1n
MjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4LTIwMTkwODExMTgzNzMy
Mzg5LTE1NjU4NTI1MS5wbmciIGFsdD0iIiBkYXRhLW1jZS1zcmM9Imh0dHBzOi8vaW1nMjAxOC5j
bmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4LTIwMTkwODExMTgzNzMyMzg5LTE1
NjU4NTI1MS5wbmciPjwvcD48cD4mbmJzcDs8L3A+PHA+6Zmk5LqG5LiK6L+w6YCa6L+H6LCD55So
5LiN5ZCM55qE5qC557uE5Lu25p2l5a6e546w5Y6f55Sf5omT5byA5LiN5ZCM55qEIFJOIOeVjOmd
ouWklu+8iOWbvuS4reesrOS6jOeCue+8ie+8jOaIkeS7rOi/mOWPr+S7peiwg+eUqOS4gOS4quag
uee7hOS7tuadpeWunueOsOOAguWUr+S4gOeahOWMuuWIq+WcqOS6juaIkeS7rOmcgOimgeiwg+eU
qOaXtuWcqCBpbml0aWFsUHJvcGVydGllcyDkuK3mt7vliqDljLrliIbkuI3lkIznlYzpnaLnmoTm
oIfor4bkvY3mnaXmuLLmn5PkuI3lkIznmoTnu4Tku7bvvIzlsLHlpb3mr5TlnKggVVJMIOS4iuaQ
uuW4puS4jeWQjOWPguaVsOi3s+i9rOWIsOWQjOS4gOi3r+eUseS4gOagt++8jOagueaNrui3r+eU
seS4iueahOWPguaVsOWcqOW6lOeUqOWxgui/m+ihjOWvueW6lOe7hOS7tueahOa4suafk+OAgjwv
cD48cD4mbmJzcDs8L3A+PHA+5ZyoIFJOIOaguee7hOS7tuS4reaIkeS7rOWPr+S7pemAmui/hyBg
dGhpcy5wcm9wc2Ag6I635Y+W5Y6f55Sf5bmz5Y+w5pC65bim6L+H5p2l55qE5Y+C5pWw5a+56LGh
77yM5aaC56S65L6L5Lit55qEIHZpZXdOYW1l77yM5YaN5qC55o2uIHZpZXdOYW1lIOWunueOsCBS
TiDlhoXpg6jnu4Tku7bnmoTmuLLmn5PvvIzlvZPnhLbkuZ/lj6/ku6Xnu5PlkIggYHJlYWN0LW5h
dmlnYXRpb25gIOadpeWunueOsOi3r+eUseaooeWdl+eahOWIh+aNouOAguiHs+S6juacgOe7iOmA
ieaLqeWTquenjeaWueW8j+WKoOi9ve+8jOWGs+Wumuadg+i/mOaYr+imgeeci+S4muWKoeeahOWI
kuWIhuWSjOWKn+iDveeahOWumuS5ieOAguebuOavlOi+g+iAjOiogOesrOS4gOenjeWPr+iDveab
tOWKoOeBtea0u+WSjOS+v+aNt+OAgjwvcD48cD4mbmJzcDs8L3A+PHA+IyMjIDUuIFJlYWN0IE5h
dGl2ZSDkuI7ljp/nlJ/lubPlj7DpgJrkv6Hljp/nkIY8L3A+PHA+5Zyo5re35ZCI5byA5Y+R5qih
5byP5LiL77yM5oiR5Lus5LiN5Y+v6YG/5YWN55qE6ZyA6KaB5ZKM5Y6f55Sf5bmz5Y+w6L+b6KGM
5pWw5o2u55qE6YCa5L+h77yM6YKj5LmI5ZyoIFJOIOS4re+8jOaIkeS7rOWmguS9leS4juWOn+eU
n+W5s+WPsOi/m+ihjOmAmuS/oeWRou+8n+WmguS9leiOt+WPluWOn+eUn+W5s+WPsOaPkOS+m+ea
hOaVsOaNruaIluWwhuaVsOaNruS8oOmAkue7meWOn+eUn+W5s+WPsOWRou+8n+S4i+mdoui/meW8
oOWbvuS+v+S7i+e7jeS6hui/meS4gOa1geeoi+OAgjwvcD48cD4mbmJzcDs8L3A+PHA+PGltZyBz
cmM9Imh0dHBzOi8vaW1nMjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4
LTIwMTkwODExMTgzNzQ0NjY1LTc2MzM1NzA4NS5wbmciIGFsdD0iIiBkYXRhLW1jZS1zcmM9Imh0
dHBzOi8vaW1nMjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4LTIwMTkw
ODExMTgzNzQ0NjY1LTc2MzM1NzA4NS5wbmciPjwvcD48cD4mbmJzcDs8L3A+PHA+5ZyoIFJOIOS4
re+8jOaIkeS7rOWPr+S7peW8leeUqCByZWFjdC1uYXRpdmUg5qih5Z2X5Lit55qEIGBOYXRpdmVN
b2R1bGVzYCBBUEkg5p2l6L+b6KGM5pWw5o2u6YCa5L+h77yM6LCD55So55qE5pa55rOV5pivIE5h
dGl2ZU1vZHVsZXMu5qih5Z2X5ZCN56ewLuaOpeWPo+WQjeensO+8jOiAjOWOn+eUn+W5s+WPsOi/
lOWbnuaVsOaNruWIsCBSTiDlubPlj7DmmK/ln7rkuo7lm57osIPvvIzku6PnoIHlpoLkuIvvvJo8
L3A+PHA+Jm5ic3A7PC9wPjxwPmBgYGphdmFzY3JpcHQ8YnI+aW1wb3J0IHsgTmF0aXZlTW9kdWxl
cyB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7PC9wPjxwPmNvbnN0IHVzZXJJbmZvID0gTmF0aXZlTW9k
dWxlcy5Vc2VySW5mbzsgLy8g6I635Y+W6Ieq5a6a5LmJ55So5oi35L+h5oGv5qih5Z2XPC9wPjxw
PmNvbnNvbGUubG9nKHVzZXJJbmZvLnVzZXJOYW1lKTsgLy8g5omT5Y2w55So5oi35ZCNPC9wPjxw
PmNvbnN0IHJvdXRlciA9IE5hdGl2ZU1vZHVsZXMuUm91dGVyOyAvLyDojrflj5boh6rlrprkuYno
t6/nlLHmqKHlnZc8L3A+PHA+Ly8g6LCD55So5Y6f55Sf6Lev55Sx6Lez6L2s5pa55rOVPGJyPnJv
dXRlci5vcGVuSG9tZSgn5Y+C5pWwJywgKHJlcykgPSZndDsgezxicj4gICAgY29uc29sZS5sb2co
cmVzKTsgLy8g5omT5Y2w6L+U5Zue5pWw5o2uPGJyPn0pOzxicj5gYGA8L3A+PHA+PGJyIGRhdGEt
bWNlLWJvZ3VzPSIxIj48L3A+PHA+6YCa6L+HIE5hdGl2ZU1vZHVsZXMg5oiR5Lus5Y+v5Lul54G1
5rS755qE6I635Y+W5oiW5Lyg6YCS5pWw5o2u57uZ5Y6f55Sf5bmz5Y+w77yM5ZCM5pe25oiR5Lus
5Lmf5Y+v5Lul5qC55o2u5Lia5Yqh6ZyA6KaB57yW5YaZ5LiN5ZCM55qEIGBCcmlkZ2VgIOaWueaz
leadpeWunueOsOaVsOaNrumAmuS/oeaooeWdl+eahOWwgeijhe+8jOavlOWmgueUqOaIt+S/oeaB
r+aooeWdl+OAgei3r+eUsei3s+i9rOaooeWdl+WPiue9kee7nOivt+axguaooeWdl+etieOAgjwv
cD48cD48YnIgZGF0YS1tY2UtYm9ndXM9IjEiPjwvcD48cD4jIyMgNi4gUmVkdXgg5p625p6EPC9w
PjxwPuWcqCBSTiDpobnnm67kuK3vvIzpmaTkuobkuI7ljp/nlJ/lubPlj7DpgJrkv6HlkozkuqTk
upLnmoTlip/og73lpJbvvIxSTiDlubPlj7Doh6rouqvkuZ/pnIDopoHlrp7njrDkuIDkupvmlbDm
ja7nirbmgIHnmoTnrqHnkIbjgILov5nph4zmiJHku6zov5jlvpforqTor4bkuIsgUmVkdXgg5p62
5p6E44CCPC9wPjxwPiZuYnNwOzwvcD48cD48aW1nIHNyYz0iaHR0cHM6Ly9pbWcyMDE4LmNuYmxv
Z3MuY29tL2Jsb2cvNzc1ODM4LzIwMTkwOC83NzU4MzgtMjAxOTA4MTExODM3NTY3MjktMTU1NjYy
Njc3Mi5wbmciIGFsdD0iIiBkYXRhLW1jZS1zcmM9Imh0dHBzOi8vaW1nMjAxOC5jbmJsb2dzLmNv
bS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4LTIwMTkwODExMTgzNzU2NzI5LTE1NTY2MjY3NzIu
cG5nIj48L3A+PHA+Jm5ic3A7PC9wPjxwPlJlZHV4IOaYr+S4gOS4queUqOS6jueuoeeQhiBSZWFj
dCDlupTnlKjnirbmgIHnmoTlrrnlmajvvIzlnKggUk4g5Lit5Lmf5ZCM5qC36YCC55So44CC5YW2
6YeH55So5Y2V5LiA5pWw5o2u5rWB55qE5pa55byP5p2l5a6e546w5pWw5o2u55qE566h55CG77yM
5ZSv5LiA5pS55Y+YIHN0YXRlIOeahOaWueazleaYr+aPkOS6pCBhY3Rpb24g5pON5L2c44CC6L+Z
5qC355qE5p625p6E5L2/5b6X5oiR5Lus55qEIFJOIOmhueebruaVsOaNruaYk+S6jue7tOaKpOaI
luaJqeWuue+8jOaUueWPmOaVsOaNrueahOa1geeoi+WuueaYk+i/vei4quWSjOaNleiOt+OAgumc
gOimgeS6huino+eahOWFt+S9k+WFs+mUruWtl+WmguS4i++8mjwvcD48cD4mbmJzcDs8L3A+PHA+
PGltZyBzcmM9Imh0dHBzOi8vaW1nMjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgv
Nzc1ODM4LTIwMTkwODExMTgzODA2MjkwLTE3ODg2OTY5NzEucG5nIiBhbHQ9IiIgZGF0YS1tY2Ut
c3JjPSJodHRwczovL2ltZzIwMTguY25ibG9ncy5jb20vYmxvZy83NzU4MzgvMjAxOTA4Lzc3NTgz
OC0yMDE5MDgxMTE4MzgwNjI5MC0xNzg4Njk2OTcxLnBuZyI+PC9wPjxwPiZuYnNwOzwvcD48cD7l
hbfkvZPmlofmoaPlj6/ku6Xlj4LogIPvvJpbaHR0cDovL2NuLnJlZHV4LmpzLm9yZy9dKGh0dHA6
Ly9jbi5yZWR1eC5qcy5vcmcvKTwvcD48cD7lvZPnhLbkvaDkuZ/lj6/ku6Xkvb/nlKjlhbbku5bn
rKzkuInmlrnlupPlrp7njrDnsbvkvLznmoTmnrbmnoTvvIzmr5TlpoIgbW9ieOOAgWR2YSDnrYnj
gII8L3A+PHA+Jm5ic3A7PC9wPjxwPiMjIyA3LiBDU1MtaW4tSlM8L3A+PHA+6Zmk5LqGIFJlZHV4
IOaetuaehO+8jFJOIOS4rei/mOWKoOWFpeS6hiBgQ1NTIGluIEpTYCDnmoTmpoLlv7XvvIzlsIbl
jp/mnKzlhbPms6jngrnliIbnprvnmoTnkIblv7Xovaznp7vliLDkuoblhbPms6jngrnmt7flkIjk
uIrvvIzkvb/lvpfmiJHku6zlj6/ku6XlnKggSlMg5Lit5YaZIENTUyDku6PnoIHvvIzkvYbov5nl
ubbkuI3ov53og4zkuYvliY3lhbPms6jngrnliIbnprvnmoTnkIblv7XjgII8L3A+PHA+Jm5ic3A7
PC9wPjxwPjxpbWcgc3JjPSJodHRwczovL2ltZzIwMTguY25ibG9ncy5jb20vYmxvZy83NzU4Mzgv
MjAxOTA4Lzc3NTgzOC0yMDE5MDgxMTE4MzgxNzYxNC0yMTI1NTY1NTE4LnBuZyIgYWx0PSIiIGRh
dGEtbWNlLXNyYz0iaHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvNzc1ODM4LzIwMTkw
OC83NzU4MzgtMjAxOTA4MTExODM4MTc2MTQtMjEyNTU2NTUxOC5wbmciPjwvcD48cD4mbmJzcDs8
L3A+PHA+Jmd0OyDnjrDlnKjpmo/nnYDnu4Tku7bljJbmpoLlv7XnmoTmtYHooYzvvIzlr7nku47n
u4Tku7blsYLpnaLnu7TmiqQgQ1NTIOagt+W8j+eahOmcgOaxguaXpeebiuWinuWkp++8jENTUy1p
bi1KUyDlsLHmmK/lnKjnu4Tku7blhoXpg6jkvb/nlKggSmF2YVNjcmlwdCDlr7kgQ1NTIOi/m+ih
jOS6huaKveixoe+8jOWPr+S7peWvueWFtuWjsOaYjuWSjOWKoOS7pee7tOaKpOOAgui/meagt+S4
jeS7hemZjeS9juS6hue8luWGmSBDU1Mg5qC35byP5bim5p2l55qE6aOO6Zmp77yM5Lmf6K6p5byA
5Y+R5Y+Y5b6X5pu05Yqg6L275p2+44CC5a6D5ZKMIENTUyBNb2R1bGVzIOeahOWMuuWIq+aYr+S4
jeWGjemcgOimgSBDU1Mg5qC35byP5paH5Lu244CCPC9wPjxwPiZuYnNwOzwvcD48cD7nu5PlkIgg
SlNYIOivreazle+8jOWcqCBSTiDkuK3kuablhpnlkoznu7TmiqQgQ1NTIOWPmOW+l+abtOWKoOS+
v+aNt++8jOS5n+aYryBXZWIg57uE5Lu25YyW5LiN5pat5Y+R5bGV55qE5b+F54S25Lqn54mp44CC
PC9wPjxwPiZuYnNwOzwvcD48cD4jIyMgOC4gUmVhY3QgTmF0aXZlIOS4rSDnmoQgRmxleCDluIPl
sYA8L3A+PHA+5Y+m5aSW77yM5Zyo5byA5Y+RIFJOIOmhueebruaXtu+8jOWumOaWueaOqOiNkOS9
v+eUqOeahOW4g+WxgOaWueW8j+aYryBgRmxleGAg5biD5bGA77yM5Zug5Li6IEZsZXhib3gg5Y+v
5Lul5Zyo5LiN5ZCM5bGP5bmV5bC65a+45LiK5o+Q5L6b5LiA6Ie055qE5biD5bGA57uT5p6E77yM
6L+Z5Lmf6Kej5Yaz5LqG6Leo5bmz5Y+w5biD5bGA5ZGI546w55qE6Zeu6aKY44CCPC9wPjxwPiZu
YnNwOzwvcD48cD48aW1nIHNyYz0iaHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvNzc1
ODM4LzIwMTkwOC83NzU4MzgtMjAxOTA4MTExODM4Mjc2MzUtNDA0MjI2MzY4LnBuZyIgYWx0PSIi
IGRhdGEtbWNlLXNyYz0iaHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvNzc1ODM4LzIw
MTkwOC83NzU4MzgtMjAxOTA4MTExODM4Mjc2MzUtNDA0MjI2MzY4LnBuZyI+PC9wPjxwPiZuYnNw
OzwvcD48cD7nm7jmr5TmiJHku6zlrqLmiLfnq6/kvb/nlKjnmoQgRmxleCDluIPlsYDvvIxSTiDk
uK3nmoQgRmxleCDluIPlsYDmnInnqI3orrjnmoTkuI3lkIzvvIzmr5TlpoIgZmxleERpcmVjdGlv
biDnmoTpu5jorqTlgLzmmK8gY29sdW1uIOiAjOS4jeaYryByb3fvvIxmbGV4IOS5n+WPquiDveaM
h+WumuS4gOS4quaVsOWtl+WAvOetieOAguWFs+S6jiBGbGV4IOW4g+WxgOeahOS7i+e7jeWPr+S7
peWPguiAg++8mltGbGV4IOW4g+WxgOaVmeeoi++8muivreazleevh10oaHR0cDovL3d3dy5ydWFu
eWlmZW5nLmNvbS9ibG9nLzIwMTUvMDcvZmxleC1ncmFtbWFyLmh0bWwp44CBW0ZsZXgg5biD5bGA
5pWZ56iL77ya5a6e5L6L56+HXShodHRwOi8vd3d3LnJ1YW55aWZlbmcuY29tL2Jsb2cvMjAxNS8w
Ny9mbGV4LWV4YW1wbGVzLmh0bWwpPC9wPjxwPiZuYnNwOzwvcD48cD4jIyMgOS4gUmVhY3QgTmF0
aXZlIOeahOeDremDqOe9sjwvcD48cD7mnIDlkI7miJHku6zku4vnu43kuIsgUk4g5Lit55qE54Ot
6YOo572y77yM6L+Z5Lmf5piv6YCJ5oupIFJOIOW8gOWPkSBBUFAg55qE5LiA5Liq6YeN6KaB5Y6f
5Zug5LmL5LiA44CC55u45q+U5Lyg57ufIEFQUCDmm7TmlrDvvIzlpKfpg73pnIDopoHnrKzkuInm
lrnlrqHmoLjnmoTmtYHnqIvvvIzogIzov5nkuKrmtYHnqIvlj6/og73kvJrlvojmhaLmiJbogIXk
uI3lj4rml7bvvIzpgYfliLDpnIDopoHntKfmgKXkv67lpI3nmoQgYnVnIOaXoOazleWPiuaXtuab
tOaWsOiAjOWvvOiHtOebtOaOpeeahOe7j+a1juaNn+WkseaYr+W+iOW4uOingeeahOmXrumimO+8
jOiAjCBSTiDnmoTng63pg6jnvbLlj6/ku6XkuIDlrprnqIvluqbkuIrop6PlhrPmiJblh4/ovbvo
v5nkuIDpl67popjnmoTlvbHlk43jgILpgqPkuYjlhbblrp7njrDljp/nkIbmmK/mgI7moLfnmoTl
kaLvvJ88L3A+PHA+Jm5ic3A7PC9wPjxwPjxpbWcgc3JjPSJodHRwczovL2ltZzIwMTguY25ibG9n
cy5jb20vYmxvZy83NzU4MzgvMjAxOTA4Lzc3NTgzOC0yMDE5MDgxMTE4MzgzODkxNS04MjE0Mzk1
MzUucG5nIiBhbHQ9IiIgZGF0YS1tY2Utc3JjPSJodHRwczovL2ltZzIwMTguY25ibG9ncy5jb20v
YmxvZy83NzU4MzgvMjAxOTA4Lzc3NTgzOC0yMDE5MDgxMTE4MzgzODkxNS04MjE0Mzk1MzUucG5n
Ij48L3A+PHA+Jm5ic3A7PC9wPjxwPuS4iuWbvuW3puS+p+mDqOWIhuS+v+WxleeOsOS6hueUqOaI
t+iuv+mXriBSTiDlupTnlKjnmoTng63pg6jnvbLmtYHnqIvjgILpppblhYjnlKjmiLforr/pl64g
QVBQ77yMQVBQIOS8muWQkSBSTiDmnI3liqHlmajor7fmsYLotYTmupDljIXvvIzlpoLmnpzotYTm
upDljIXmnKrmm7TmlrDliJnor7vlj5bmnKzlnLDnvJPlrZjotYTmupDvvIzlpoLmnpzlvIDlj5Ho
gIXkuLrkuobop6PlhrMgYnVnIOmHjeaWsOabtOaWsOS6huacjeWKoeWZqOS4iueahOi1hOa6kOWM
he+8jOmCo+S5iCBBUFAg5ouJ5Y675ZCO5Lya57yT5a2Y6LW35p2l77yM5b6F55So5oi35LiL5qyh
6L+b5YWl5ZCO5YaN6L+b6KGM5pu05paw44CC6L+Z5L6/5pivIFJOIOeDremDqOe9sueahOa1geeo
i+OAgjwvcD48cD4mbmJzcDs8L3A+PHA+5Zyo5pys5Zyw5byA5Y+R5pe277yM5oiR5Lus5LiN6Zq+
5Y+R546w5b2T5oiR5Lus5Zyo6L+Q6KGM6LW35p2l55qEIFJOIOmhueebruS4reS/ruaUueS7o+eg
geaXtu+8jOWGjeasoeS7jiBBUFAg6L+b5YWlIFJOIOmhtemdou+8jOacrOWcsOe7iOerr+S8muWG
jeasoeWKoOi9veS4gOasoeabtOaWsOWQjueahOi1hOa6kOaVsOaNru+8jOi/meS5n+aYryBSTiDn
g63pg6jnvbLnmoTkvZPnjrDjgII8L3A+PHA+Jm5ic3A7PC9wPjxwPuWQjOagt+e6v+S4iueahOeD
remDqOe9suWImemcgOimgeWwhuaIkeS7rOaJk+WMheWQjueahCBSTiDotYTmupDkuIrkvKDliLDm
nI3liqHlmajkuIrkvpsgQVBQIOivu+WPluadpeWunueOsOOAgjwvcD48cD4mbmJzcDs8L3A+PHA+
PGltZyBzcmM9Imh0dHBzOi8vaW1nMjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgv
Nzc1ODM4LTIwMTkwODExMTgzNDIzMTU3LTM2NDIxOTE2Mi5wbmciIGFsdD0iIiBkYXRhLW1jZS1z
cmM9Imh0dHBzOi8vaW1nMjAxOC5jbmJsb2dzLmNvbS9ibG9nLzc3NTgzOC8yMDE5MDgvNzc1ODM4
LTIwMTkwODExMTgzNDIzMTU3LTM2NDIxOTE2Mi5wbmciPjwvcD48cD4mbmJzcDs8L3A+PHA+5oiR
5Lus5Y+v5Lul5omL5Yqo5omn6KGM5omT5YyF44CB5LiK5Lyg5Y+R5biD5rWB56iL77yM5b2T54S2
5Li65LqG5YeP5bCR5Lq65Li65bmy6aKE77yM5a6e546w5YmN56uv6Ieq5Yqo5YyW77yM5oiR5Lus
5Lmf5Y+v5Lul5oqK6L+Z5Z2X5rWB56iL5Lqk57uZ5p6E5bu65bmz5Y+w5Y676Ieq5Yqo5omT5YyF
6YOo572y77yM6L+Z5L6/6ZyA6KaB5pCt5bu65LiA5Liq5ZCO5Y+w57O757uf6L+b6KGM566h55CG
44CCPC9wPjxwPiZuYnNwOzwvcD48cD4jIyDnu5Por608L3A+PHA+5pys5paH5LuL57uN5LqGIFJl
YWN0IE5hdGl2ZSDmt7flkIjlvIDlj5HnmoTljp/nkIbkuI7lrp7njrDpgLvovpHjgILlj6rmnInl
hYjkuobop6Pljp/nkIbvvIzmiY3og73pq5jmlYjnmoTmipXlhaXpobnnm67nmoTlvIDlj5HkuK3v
vIzogIzlhbPkuo4gUk4g6Ieq6Lqr55qE5Yqf6IO95a6e546w5aSn5a625Y+v5Lul55u05o6l6ZiF
6K+75a6Y5pa55paH5qGj77yM6L+Z6YeM5oiR5Lmf6aKd5aSW5o+Q5L6b5LiA5Lqb5YWz5LqOIFJO
IOeahOWPguiAg+i1hOaWme+8mjwvcD48cD4qIFtSZWFjdC1OYXRpdmXlrabkuaDmjIfljZddKGh0
dHBzOi8vZ2l0aHViLmNvbS9yZWFjdG5hdGl2ZWNuL3JlYWN0LW5hdGl2ZS1ndWlkZSk8YnI+KiBb
5YiG5LqrIDUwIOS4quWujOaVtOeahCBSZWFjdCBOYXRpdmUg6aG555uuXShodHRwczovL2p1ZWpp
bi5pbS9wb3N0LzU4ZjM3Y2IzNjFmZjRiMDA1OGY5ODI0YSk8YnI+KiBb57uZ5omA5pyJ5byA5Y+R
6ICF55qEUmVhY3QgTmF0aXZl6K+m57uG5YWl6Zeo5oyH5Y2XXShodHRwczovL2p1ZWppbi5pbS9w
b3N0LzU4OTgzODhiMTI4ZmUxMDA2Y2I5NDNlMyk8YnI+KiBbMzDlpKnlrabkuaBSZWFjdCBOYXRp
dmXmlZnnqItdKGh0dHBzOi8vZ2l0aHViLmNvbS9mYW5nd2VpNzE2LzMwLWRheXMtb2YtcmVhY3Qt
bmF0aXZlKTwvcD48cD48YnI+5rOo77ya5pys5paH6YOo5YiG5Zu+5L6L5Y+C6ICD6Ieq44CKUmVh
Y3QgTmF0aXZlIOenu+WKqOW8gOWPkeWunuaImOOAi+S4gOS5pjwvcD4=">​</div>




</div><br><br>
来源:https://www.cnblogs.com/luozhihao/p/11335948.html
頁: [1]
查看完整版本: React Native 混合开发与实现