47Log

没错,就是我

  • 首页
  • 代码
  • 设计
  • 感悟
  • BUG肥猿瘦
  • 搜索

越秀配镜之旅

发表于 2021-01-02  |  分类于 分享  |  暂无评论

IMG_0500

  1. 使用相机自拍而而不是使用镜子
    大致挑选的时候可以使用镜子,当要实际对比的时候使用相机自拍对比。
    由于我近视程度比较深,带上样式眼镜没法看清自己的样子,只能模糊看到,不能精细的对比,最好就是来个正面角度的自拍,然后带上眼镜查看。同时这样非常方便不同店铺留档查看

  2. 朋友要选对
    带个审美要靠得住的朋友,最好是女生,主要是因为女生的一般都比较在线,同时在一个异性的角度看会好很多。

  3. 多选择
    去不同的店多尝试,如果没有找到非常合适的,千万不能将就,眼镜算是一个大头商品,而且换的周期非常长,基本决定了你一年的样子

  4. 价格选择
    去货源地,也就是越秀区,可以找到比较便宜的眼镜,外面几千的镜片和镜架可以做到一千多。我这个钛合金镜架加上最薄的明xxx镜片,外面不上千下不来。

阅读全文 »

Docker 网络调试工具

发表于 2020-12-07  |  分类于 分享  |  暂无评论

推荐这个镜像进行网路调试,network-multitool

里面基本集成了需要的工具,不需要再安装

阅读全文 »

7. swift & kotlin 的字符串常用操作

发表于 2020-09-17  |  分类于 代码  |  暂无评论

值类型

swift 的字符串是值类型,这点和 kotlin 是不一样的,kotlin 来自于 java,所以和java 一样,是对象类型。

swift 并不是每次赋值字符串都会发生拷贝,只有新的对象发生改变的时候才会发生值拷贝

可变与不可变

swift 的 String 类型可变与不可变取决于是否可以定义的字段

let str = "test" // 不可变
var str2 = "test" // 可变

感觉很完美的继承了 swift 定义的风格
kotlin 是 Jvm 语言,所以所有的字符串都是不可变的

val str1 = "test" // str1 指向的对象不可变
var str2 = "test" // str2 指向的对象可变

因此, Swift 的 字符串可以这样操作

var str = "test"
str.append("test")

而 kotlin 是没有这样方法的,只能生成一个新的字符串赋值给新的对象

var str = "test"
str = str + "test"

当然,kotlin 直接使用 StringBuilder 就能或者一致的体验了

var str = StringBuilder("test")
str.append("test")

总得来说,swift 这个地方定义要更高一筹

阅读全文 »

6. swift & kotlin之字符串

发表于 2020-09-16  |  分类于 代码  |  暂无评论

它们字符串定义和实现都是一样的

swift 定义

let str = "我是一个串"
let str = String("我是一个串")

kotlin 定义

val str = "我是一个串"
val str = String("我是一个串")

但是其他扩展用法来说 swift 更强大,我也觉得更好用

替换字符

swift

let number = 1
let str = "我是 \(number)条狗"

kotlin

var number = 1
var str = "我是 $number 条狗"

Groovy

def number = 1
def str = "我是 $number 条狗"

typescript

const number = 1
const str = `我是 ${number} 条狗`

通过对比可以发现,天下语言大同,唯独 typescript 搞特殊。
但是这里面的使用方法我更喜欢 kotlin 和 groovy 的写法

阅读全文 »

3. swift & kotlin 的 Optional

发表于 2020-09-12  |  分类于 代码, 分享  |  暂无评论

swift

swift 中的 Optional 定义是这样的

let str : String? = nil

拆开就是这样拆开

print(str!)

同时语言级别提供几个语法糖,比如可以这样

if let myStr = str {
    // 这里就不用解开了,相当于 let 给你解开了
    print(myStr.count)
}

实际上的实现呢是通过系统官方的一个 Optional 类来实现的,加上 ? 号只是方便定义而已,比如一开始的代码也可以这样写

let str : Optional<String> = "112"

有没有发现这个和 Java 的 Optional 巨相识

后面的操作其实也就是隐式调用这个类的方法而已,不展开了,具体自己看源码。

kotlin

回到 kotlin 这里,kotlin 其实也有类似的定义,也不能说类似,几乎差不多,但是更强大

定义:

val str: String? = "11"
if (str != null){
    // 注意这里是不需要像swift那么麻烦的,需要赋值,这里kt会自动推断,不需要自己拆包
    print(str.lenght)
}

拆包:

// 嗯,kt 的拆包是两个叹号,比 swift 多一个
println(str!!.length)

高级组合拳:
kotlin 可以使用各种作用域函数进行快速的操作,这点比 swift 要强很多

根据 kotlin 的源码实现,其实 swift 其实也是可以实现这样的方法的,但是官方就是没有,我觉得很诡异

// 通过这个方式,就能直接把一个可选的值变成非空的it,然后进行操作,这边要比 swfit 强
str?.let{ println(it) }

而且这样的快速操作方法,kotlin 有五个,分别是 let,run,with,apply和 also。

takeIf 和 takeUnless 不属于这个类别

typescript作为前端的希望,不好意思,它没有这个东西😀

阅读全文 »

9月是个好月份

发表于 2020-09-12  |  分类于 代码  |  暂无评论

原版

  • 9.2 Nvidia RX30x0 显卡发布,4k游戏可及
  • 9.3 Intel正式发布了代号Tiger Lake的第11代低功耗酷睿处理器,牙膏挤爆
  • 9.9 Galaxy Z Fold2 5G 国内发布
  • 9.9 android 11 正式发布,同月各大国内厂商将会推送,所以要适配了
  • 9.15 苹果秋季发布会
  • 9.26 楼下喜茶要开了[狗头]

NVIDIA-GeForce-RTX-3080-Graphics-Card-scaled

Samsung-Galaxy-Fold-2-Concept-Ben-Geskin

ac2ab1c0-f1e7-11ea-aecc-6ddca9711160

苹果版本

  • ✅ 9.2 Nvidia RX30x0 显卡发布,4k游戏可及
  • ✅ 9.3 Intel正式发布了代号Tiger Lake的第11代低功耗酷睿处理器,牙膏挤爆
  • ✅ 9.9 Galaxy Z Fold2 5G 国内发布
  • ✅ 9.9 android 11 正式发布,同月各大国内厂商将会推送
  • ☑️ 9.15 苹果秋季发布会
  • ☑️ 9.26 楼下喜茶要开了[狗头]

欢迎补充[狗头]

阅读全文 »

4. swift & kotlin 元组

发表于 2020-09-06  |  分类于 代码  |  暂无评论

对于 swift 来说,这就是个系统帮你快速创建的类,主要你想打包几个字段的时候非常好用,也用不着为了打包定义几个类。

定义代码如下

let error = (1,"你就是错了",1,1,22,3,3,3,3,3)
print(error)

这个元祖里面是不限制数量,同时也支持给字段命名

let error = (code: 1, message: "错了就是错了")
print(error)
//output  (code: 1, message: "你的名字")

支持打包当然也直接拆包

let error = (code: 1, message: "错了就是错了")
let (code , message) = error
print("code : \(code),message \(message)")
//out code : 1, message 错了就是错了

这货在 kotlin 里面也有,但是没有那么强大

val error = Pair(1,"错了就是错了")
val error2 = Triple(1, "错了就是错了","我是第三个")
println("first : ${error.first}, second : ${error.second}")
println(error)

// output
// first : 1, second : 错了就是错了
// (1, 错了就是错了)

kotlin 是通过 Pair 和 Triple 这两个类实现的,是需要手动调用,而且目前最多支持 3 个,不支持命名字段,在我看来就是有语言加成的类,当然它也支持解包

val (code,message) = error
println("code : $code, message : $message")

但是和 swift 不同的是,kotlin 中元组的值是一定不可变的,比如 swfit 中

var error = (code: 1, message: "错了就是错了")
error.code = 1

这样是没问题的,但是 kotlin 因为本质就是个类,它的定义决定了是不能变的

public data class Pair<out A, out B>(
    public val first: A,
    public val second: B
)

所以这样操作是不行

var error = Pair(1, "错了就是错了")
error.first = 1

总结就是,苹果爸爸技高一筹,kotlin 因为要兼容 Java 语言做了很多妥协

阅读全文 »

5. swift & kotlin Optional 的用途

发表于 2020-09-06  |  分类于 代码  |  暂无评论

用了 optional 是不是不会为空呢?

这个显然不用问的,肯定是能够为空的,难道程序还能拦住人不成?
比如这样的代码

func jump(str : String){}
jump(nil!) // 我这样写你能奈我何?

那么这个东西的用处是什么?

声明不为空

为了明确各自的边界
比如 Java 的一个方法

void jump(String name){    
    if(name.lenght != 0){
        // do
    }
}

如果外部传入空值怎么办?
第一波尝试,增加 NouNull 注解

void jump(@NouNull String name){    
    if(name.lenght != 0){
        // do
    }
}

但是注解只是编译提醒,人家不看编译提醒还是传了空怎么办?
那就第二波修改,null 检查

void jump(@NouNull String name){    
    if (name == null){
        throw new IllegalArgumentException("参数不能为空");
    }
    if (name.lenght != 0){
        // do
    }
}

第二波修改明显就能够防止问题的,但是如果让你每个方法都这样写一遍,是不是感觉很累?

kotlin 简化了这种写法

fun jump(name: String) {
    if(name.isNotEmpty()){
       //do  
    }
}

当你尝试这样调用的时候 jump(null) 会编译直接报错,因为这里声明的不是可选类型,不能为空。
如果你这样写 jump(null!!)那就会运行时候报错,自动检查空

swift 也是一样

func jump(name: String) {
    if ( name.lenght != 0){
       //do  
    }
}

减少判空的噪音

同样的java代码,要判空需要这样写

void jump(String name){    
    if(name != null && name.lenght != 0){
        // do
    }
}

但是 kotlin 只需要这样

fun jump(name: String?){    
    if(name?.lenght != 0){
        // do
    }
}

swift 也是这样

func jump(name: String?){    
    if(name?.lenght != 0){
        // do
    }
}

其实我觉得最方便的时候是有个类需要接受一个 callback。
这个 callback 是可以为空的,然后你就需要每个使用的地方都加个空判断,就比如下面这样的代码

class PushManager{
    private PushCallback pushCallback;
    
    private void onPush(){
        if(pushCallback != null){
            pushCallback.onGetPushData();
        }
    }
}

但是如果换成 kotlin 编写的话就非常愉悦了

class PushManager{
    private var pushCallback : PushCallback?;
    
    private onPush() {
        pushCallback?.onGetPushData();
    }
}

简直和不用写判空一样,这样减少了很多代码噪音,让开发人员更加专注于编写代码本身

阅读全文 »

2. swift & kotlin 变量可变与不可变

发表于 2020-09-06  |  分类于 代码  |  暂无评论

两边都有可变和和不可变的定义就是名字不太一样

swift 是这样

let 不变 = 1
var 可变 = 1

kotlin 是这样

val 不可变 = 1
var 可变 = 1

其实就是对应 Java 的

final int 不可变 = 1;
int 可变 = 1;

因为平常开发中不可变用的其实比较多,java 这个天天敲 final 的确让人受不了,kotlin 简写这个还是挺好的

这里插一下别的语言

typescript 是这样

const 不可变 = 1
var 可变 = 1

就你不一样?作为现代语言能不能统一一下????

阅读全文 »

1. swift & kotlin数据类型

发表于 2020-09-06  |  分类于 代码  |  暂无评论

基本数据类型

类型 大小(字节数) 区间值(自己算,不写)
Int8 1
UInt8 1
Int32 4
Int64 8
UInt32 4
UInt64 8
Float 4
Double 8

无符号类型 kt 其实也有,只不过在1.4版本的实验特性上

Int 类型和 Kotlin 不一样的,Int类型 Swift 是根据平台来的,这点和 C 倒是挺像的,Kotlin 是JVM语言,就是表示这货不同平台都是那么多位的,我觉得这个设计比Swift更好

Bool 类型

其实就是 true or false,别说 kt,java 都用几百年了

let isMy: bool = false

if(isMy){
    print("你的")
}else{
    print("我的")
}

kotlin 实现其实也差不多,就是名字不太一样,人家是boolean

val isMy: Boolean = false
if (isMy) {
    print("你的")
} else {
    print("我的")
}

类型别名

typealias AudioSimple = Int
let b : AudioSimple = 1

kotlin 是把这个代码把 let 改为 val 放到 kotlin 直接就可以运行,毫无违和感

typealias AudioSimple = Int
val b : AudioSimple = 1
阅读全文 »

如何移除 gradle 远程依赖中多余的 package

发表于 2020-06-28  |  分类于 小记录  |  暂无评论

原文链接

The exclude method of the configuration closure for a dependency excludes transitive dependencies. So, if your module dependency depends on other modules, you can exclude them from your build. You can check out the transitive dependencies of the 'com.facebook.android:facebook-android-sdk:4.14.0' module on its Maven repository info page.

If the BundleJSONConverter class exists in a transitive dependency, you can exclude the specific module in the same way you are trying now. Just specify the group, the module and the version, like you do for dependencies.

If you just want to exclude one class for a dependency jar, take a look at the jar jar links tool and its Gradle plugin. It allows you to alter included jars, e.g. to change packages or remove classes.

The following (shortened) example shows the usage of the plugin and some methods to alter the dependency jar:


apply plugin: 'org.anarres.jarjar'

compile jarjar.repackage {
    from 'org.apache.hive:hive-exec:0.13.0.2.1.5.0-695'

    archiveBypass "commons*.jar"
    archiveExclude "slf4j*.jar"

    classDelete "org.apache.thrift.**"
    classRename 'org.json.**', 'org.anarres.hive.json.@1'
}
阅读全文 »

找不到androidx.databinding.DataBindingComponent的类文件

发表于 2020-06-27  |  分类于 小记录  |  暂无评论

databinding 新的特性导致的,需要在 gradle.properties 手动关闭增量编译

android.enableExperimentalFeatureDatabinding=false
阅读全文 »

禁止 macOS 的更新提示

发表于 2020-06-06  |  分类于 分享  |  暂无评论

终端中敲入

sudo softwareupdate --ignore "macOS Catalina"

如果需要开启则通过这个

sudo softwareupdate --reset-ignored
阅读全文 »

本地搭建代理代理 v2ray 协议猜想

发表于 2020-05-31  |  分类于 分享  |  暂无评论

用途

因为每个人配置v2ray 其实比较麻烦,如果每个人直接使用 proxy-switchyomega 这个插件就会简单很多。目标是实现所有人简单的上网。

部署条件

  1. 需要有公网IP
  2. 内网需要有一台机器跑 v2ray 和 nginx

拓扑图

描述

  1. 用户通过 proxy-switchyomega 设置 https 代理
  2. 本地由 caddy 或者 nginx接受到代理,直接代理到本地的 v2ray 上的 http 协议

一定是要 https 代理,这样才能保护数据和账号密码
本地代理可以增加路径认证,因为https是抓不到路径的,所以路径上加账号密码即可

阅读全文 »

发现一个官方的布局异步加载

发表于 2020-05-31  |  分类于 分享  |  暂无评论

阅读全文 »

Gitlab Ci 的 CI_DEBUG_TRACE

发表于 2020-05-29  |  分类于 分享  |  暂无评论

这个东西的作用是在 GitlabCi 的日志输出界面输出更多用于方便调试的日志。

官方建议是写在 .gitlab.yml 上, 如下

variable:
    CI_DEBUG_TRACE: true

这样就会导致一个问题,每次当你想要调试的时候,你都要提交一个代码把这个东西打开,这样有点蛋疼。
后面我发现https://gitlab.com/{namespace}/{project}/-/settings/ci_cd 这个地方的也是可以设置Variable的。实验了以下,这个地方也是有效的,只要在这里

填上这个 CI_DEBUG_TRACE就能直接显示所有调试内容了,这样做就不需要每次都提交代码才能显示调试的内容。

这货有个小缺点,就是所有的 ci/cd 都会生效

阅读全文 »

Groovy 输出命令信息到控制台

发表于 2020-05-29  |  分类于 分享  |  暂无评论

如果直接用以下这个

pngquantCmd.consumeProcessOutput(System.out, System.err)

会创建一个线程执行命令,命令行会跳过。

如果使用下面这个

pngquantCmd.waitForProcessOutput(System.out, System.err)

就会等到执行完成执行下一句,平常应该使用下面这个

阅读全文 »

mac 中快速使用 Android Studio 打开某个目录

发表于 2020-05-24  |  分类于 分享  |  暂无评论

效果图

阅读全文 »

升级到 AngularCli9 后 ngx/cache 不能运行问题

发表于 2020-05-18  |  分类于 小记录  |  暂无评论

关键字

"Can't resolve all parameters for MemoryCacheService"
"Can't resolve all parameters for LocalStorageService"

问题描述

升级到 AngularCli 9 之后 ngx-cache 模块加入后,运行会出现上述问题

解决方案

注入方式由

{ provide: CACHE, useClass: (MemoryCacheService) }

改为

{ provide: CACHE, useClass: (MemoryCacheService), deps: [PLATFORM_ID] }

其实就是增加了 PLATFORM_ID 作为参数

详情在 Angular 9 + Ivy #128

阅读全文 »

Portainer 添加 endPoint

发表于 2020-05-13  |  分类于 小记录  |  暂无评论

portainer 添加 endpoint 有两种方式

  • 直接连接到对应的 portainer agent
  • 使用 edge agent 代理连接

直连模式

使用这个模式,需要机器有公开的 9000 端口(非9000也可以,自己改),然后 portainer 会直接尝试连接机器上的 portainer agent。
这个模式下,可以获得 portainer 所有功能

代理模式


这个模式下,是在机器上部署一个 edge 代理,然后这个代理自己连接到 portainer 上。这个模式就不需要机器公开任何接口,会方便不少。
但是目前发现一个功能不能使用,就是下图中的 ServiceHook

这个功能对于 ci/cd 继承自动化发布来说很好用,要是用不到可以无视。

注意点

建议都使用 swarm 模式,不然 stack 只能支持到 version 2 版本,conf 和 serect 功能也不能使用。

小结

优先使用 agent 模式,如果不能暴露端口,比如家里网络,就要使用 edge agent 模式

阅读全文 »

使用 Docker Swarm 搭建 WordPress

发表于 2020-05-12  |  分类于 分享  |  暂无评论

起因

我曾经把 wordpress 搭建在 Vultr 上,但是因为众所周知的原因,这个地方访问越来越慢。再后来我选择了新浪云,新浪云的确够便宜,也很不错,但是要备案,还有评论功能估计要阉割,想想还是算了,找个香港的主机搭建 wordpress 即可。

购买主机

我这里选择的是阿里云的轻量应用服务器,这个主机的好处就是便宜,够用。
比如我选择的香港的主机,一个月只需要 24 块钱,一核心一G内存,网速为 30Mbps,磁盘空间 25GB,月流量 1TB。

配置如下图

初始化 docker 环境

虽然上面有一件安装wordpress的功能,但是我不推荐,因为配置都太老了

最终我选择的是 ubuntu18.04 系统,直接用下面的命令即可完成安装 docker 并且初始化 docker swarm

curl -o- -L https://gist.githubusercontent.com/hangox/e679464f35dc2a78920e6249a21d7958/raw/c5541e38979dca1e3e1e9704ad171ed2f0556fa1/ubunut-install-docker.sh | bash
阅读全文 »

发现搭建一个暗网其实很简单

发表于 2020-05-11  |  分类于 感悟  |  暂无评论
  1. 搭建一个或者云服务商买租用一个 discuz 论坛
  2. 增加一个 robot.txt 协议,写上 "Disallow: /"
  3. 然后改为邀请码才能注册
  4. 然后把主题改为黑色😊

大部分认为暗网其实就是这样,不能被搜索引擎搜录,一般人不能进入,主题还是黑色的,完美

阅读全文 »

Homebrew 安装软件后路径配置

发表于 2020-05-09  |  分类于 小记录  |  暂无评论

所有 Homebrew 安装的软件其实都会在 /usr/local/opt/ 这个地方创建一个软应用,指向的都是当前命令使用的软件版本,比如我虽然安装了两个 git,一个24版本,一个26版本,命令行可以使用的是26版本 ,所以这个路径 /usr/local/opt/git/bin/git的版本就是 26 版本。
这种目录最常见用于配置 IDE 各种环境的路径,比如说 git

相较于以前直接配置到具体版本的路径上,每次升级都要改,这个要方便不少。

阅读全文 »

Docker Swarm Volume 问题记录

发表于 2020-05-09  |  分类于 小记录  |  暂无评论

Docker Swarm 或者 Docker Compose 部署的容器有个问题,如果你使用的是 Docker 自动创建的 Volume ,也就是这种方式

version: '3'

services:
  caddy:
    image: jayfong/caddy-dnspod
    environment:
    volumes:
      # Caddy 自动生成的 SSL 证书
      - certs:/caddy/certs
    ports:
      - 2015:2015
    restart: unless-stopped
volumes:
  certs:

这个 Volume 最终的名字是 caddy-home_cert ,因为我指定的 docker stack 名字为 caddy-home, 如果你下次更新,就必须要指定一样的名字,不然是不能到达一样的文件目录的。如果确实不能弄成一样的名字,又不想挪动文件,其实还是有办法的,可以尝试这样写

volumes:
  certs:
    external: true

这样 docker 就不会尝试创建 certs 了 ,但是注意的是,这个东西需要提前创建好,不然是会服务部署失败的

阅读全文 »

禁止通知mac dock弹跳

发表于 2020-05-09  |  分类于 小记录  |  暂无评论
# 不弹跳开启
defaults write com.apple.dock no-bouncing -bool TRUE
# 不弹跳关闭
defaults write com.apple.dock no-bouncing -bool FALSE
阅读全文 »

ubuntu 机器快速配置 Docker

发表于 2020-05-09  |  分类于 小记录  |  暂无评论

这个脚本会安装 docker 并开启 docker swarm

curl -o- -L https://gist.githubusercontent.com/hangox/e679464f35dc2a78920e6249a21d7958/raw/c5541e38979dca1e3e1e9704ad171ed2f0556fa1/ubunut-install-docker.sh | bash
阅读全文 »

电脑升级到i9-9900K感受

发表于 2020-04-09  |  分类于 代码  |  暂无评论

今年年初,我把我电脑从 i5-7400 升级到 i9-9900K,也就是从 4 核心 4 线程最高 3.6 主频的 U 升级到 8 核心 16 线程最高主频 5.0 主频的U。

我把 i9 超频到全核心 5.0G

在工作中也用了一个多月了,说说我在使用的过程中感受到的提升吧,我其实经常进行 App 的打包去验证问题,我就以这个场景说明一下问题

运行命令

/gradlew clean
/gradlew :cc-start:assembleDebug --no-build-cache

新电脑用时

旧电脑用时

差了 42秒,别看这 42秒不重要,有时候验证一个问题,都是需要清洁构建,我曾经试过验证一个问题一天需要构建十几次,能省下不少时间。同时,因为打包并不能把新U所有的性能压榨出来,这个时候我是可以做别的工作的,但是旧的U是已经完全卡死了

接着我运行了更吃 CPU 的打包场景

阅读全文 »

华为畅享9s 手机启动图变形问题调查结论与过程

发表于 2020-04-05  |  分类于 BUG肥猿瘦, 感悟  |  暂无评论

关键字

  • layer-list
  • 启动图
  • 华为荣耀
  • windowBackground
  • 变黑

问题描述

在部分华为手机上启动,启动图会变成如下模样

c4198cabae55da33a73fed3b9dbd2a4a
而我们正常的启动图是这个模样
Screenshot_20200405-154051

有意思的地方在于,这个包对应的提交,我们同时打了一个包名不一样的包,用于mtl测试,但是那个包完全没问题。

阅读全文 »

记录一个LifeCycle 多线程使用导致的崩溃

发表于 2020-04-05  |  分类于 BUG肥猿瘦, 感悟  |  暂无评论

关键字

  • lifecycle
  • 多线程
  • java.lang.IllegalArgumentException
  • bug
  • android
  • androidx

问题描述

在调用 getLifecycle().addObserver() 的时候报出这样的错误

java.lang.IllegalArgumentException  
at androidx.lifecycle.LifecycleRegistry.upEvent(SourceFile:279)  
at androidx.lifecycle.LifecycleRegistry.forwardPass(SourceFile:293)  
at androidx.lifecycle.LifecycleRegistry.sync(SourceFile:333)  
at androidx.lifecycle.LifecycleRegistry.addObserver(SourceFile:189)  
阅读全文 »

查看 Gitlab 版本

发表于 2020-04-03  |  分类于 小记录  |  暂无评论

访问链接 https://host/help

阅读全文 »

文章导航

1 2 3 … 5
avatar

hangox

150 文章
6 分类
47 标签
RSS
友情链接
© 2019 - 2023 hangox
Powered by WordPress
Theme NexT WP