0.1.3 • Published 12 months ago

metadesktop v0.1.3

Weekly downloads
-
License
ISC
Repository
-
Last release
12 months ago

更新

1. 引入文件 import { metadesktop } from 'metadesktop' 修改为 import { metadesktop } from MetaDesktop'

介绍

metadesktop是一个基于vue3的框架,中文名称云桌面,一个用于在web端实现与window系统类似的桌面管理系统

开始使用

安装

metadesktop框架依赖于vue3构建工具,在使用之前,确保自己的vue版本为3及以上版本

npm install metadesktop

在vue3项目中引入

在vue项目的入口文件main.js中引入两个相关依赖文件,metadesktop.js和metadesktop.css

import  { MetaDesktop } from  'metadesktop'
import  'metadesktop/dist/metadesktop.css'

使用 Vue.use 进行安装

createApp(App).use(MetaDesktop).mount('#app')

如果你使用了其他第三方插件,并不会对系统产生影响,可以放心使用,比如下面使用了vuex和vue-router

createApp(App).use(metadesktop).use(store).use(router).mount('#app')

main.js 完整代码:

import { createApp } from  'vue'
import  App  from  './App.vue'
import  router  from  './router'
import  store  from  './store'
import  { metadesktop } from  'metadesktop'
import  'metadesktop/dist/metadesktop.css'

createApp(App).use(metadesktop).use(store).use(router).mount('#app')

创建桌面

metadesktop内置了一个MetaDesktop组件,他是metadesktop系统的入口组件,我们在App.vue中使用它

<template>
	<div  id="app">
		<MetaDesktop/>
	</div>
</template>

我们使用浏览器查看当前项目,会发现桌面上可能什么也没有,这是因为MetaDesktop组件的大小依赖于父元素的大小,我们给 id="app"的div设置css属性,让他铺满整个浏览器窗口

<style  lang="less">
	#app{
		width: 100vw;
		height: 100vh;
	}
</style>

我们重新打开浏览器,如果看到左下脚的window图标,就证明创建桌面成功了。此时的桌面一片空白,是因为我们还没有加入我们自己的桌面图标,后面会详细介绍。

App.vue 完整代码:

<template>
	<div  id="app">
		<MetaDesktop/>
	</div>
</template>

<script>
export  default {
}
</script>

<style  lang="less">
	#app{
		width: 100vw;
		height: 100vh;
	}
</style>

Application应用类、ApplicationManage管理类和 MetaWindow 窗口类

我们先来看一个例子,以此来了解这两个类。 在app.vue组件的生命周期函数 mounted 中加入如下代码。

let appManege = this.$System.getApplicationManage();
appManage.addApplicationWeb({
	title:"哔哩哔哩",
	icon:  "https://www.bilibili.com/favicon.ico?v=1",
	href :"https://www.bilibili.com/"
})

如果你是国内的话,你可以看到,我们创建的桌面上出现了哔哩哔哩的图标,点击图标,弹出了一个窗口,内容为哔哩哔哩网站的内容。如果是在国外,你可以随意找一个网站。

上面的代码,通过$System的getApplicationManage函数获取了一个ApplicationManage对象,不难猜出ApplicationManage对象是用来管理应用的。

Application对象是用来生成 MetaWindow 窗口的,所以需要创建一个MetaWindow 窗口之前,就需要创建一个Application对象。Application对象生成窗口需要依赖一个vue的组件,以组件内容生成窗口,而上面可以直接使用网站生成窗口,是因为内部已经默认使用了一个Web组件,通过iframe来加载网页。

Application对象生成窗口会返回一个MetaWindow 对象,通过MetaWindow 对象可以操作生成的MetaWindow窗口,在组件中,可以通过props获取到对应的MetaWindow 对象。

1.ApplicationManage

ApplicationManage里需要关注的方法只有三个:addApplication,addApplicationWeb,remove。 addApplication和addApplicationWeb都是用来创建应用,而remove是用来移除应用,addApplication需要传递一个组件对象,而addApplicationWeb不需要,因为addApplicationWeb是addApplication的一个特例,内部已经使用了Web组件,Web组件是内部的一个用来加载网页组件。

addApplication

// addApplication(Object component,Bool showDesktop)
// component: vue组件
// showDesktop:可选, 应用图标是否显示在桌面上
// return: Application 对象

addApplicationWeb

// addApplicationWeb(Object value,Bool showDesktop)
// value: 传递值对象,title:标题,icon:图标,href:网址
// showDesktop: 应用图标是否显示在桌面上
// return: Application 对象

remove

// remove(Application application)
// application: 需要移除的应用对象

2.Application

Application对象里,需要现在关注的只有一个:open,用来启动一个新窗口,一个应用可以启动多个窗口,不过因为默认只能启动一个窗口,所以现在只能启动一个,想要启动多个,后面会提到,open按需要可以传递一个值对象。 open

// open(Object value)
// value:可选,传递值对象
// return: MetaWindow 对象

3.MetaWindow

MetaWindow 里需要关注的东西有点多,有窗口配置WindowConfig,关闭窗口、隐藏窗口、全屏窗口函数,事件Event。

(1). WindowConfig对象里有很多属性,用来设置窗口,所有属性看下面的表。设置WindowConfig推荐在组件中设置。

export  default {
	windowConfig:{
		windowWidth:"600px",
		windowHeight:  "90%",
		showBottomBar:  false,
		showTitleBar:  false,
		isBoxShadow:  false,
		isOverflow:  false,
		showAddmin:  false,
		showDesktop:  false,
	},
	data() {
		return {
		}
	},
	mounted(){},
}
属性
属性名描述类型默认值
icon窗口的图标,是一个资源地址或svg代码string默认图标
icon_svg是否启用svg图标,如果启用,icon的内容应该是svg代码而非资源地址boolfalse
showTitleBar是否显示tar栏booltrue
title窗口名称stringnull
titleBarBackground标题栏背景stringnull
titleBarFontColor标题字体颜色stringnull
titleBarFontSize标题字体大小,必须带单位stringnull
titleBarFontWeight标题字体粗细stringnull
titleBarFontFamily标题字体stringnull
titleBarCancelBackground标题栏 关闭窗口按钮 背景色stringnull
titleBarFullScreenBackground标题栏 全屏窗口按钮 背景色stringnull
titleBarHideBackground标题栏 隐藏窗口按钮 背景色stringnull
windowTop窗口距离桌面顶部位置,必须带单位stringnull
windowLeft窗口距离桌面左边位置,必须带单位stringnull
windowBottom窗口距离桌面低部位置,必须带单位stringnull
windowRight窗口距离桌面右边位置,必须带单位stringnull
windowWidth窗口宽度,必须带单位stringnull
windowHeight窗口高度,必须带单位stringnull
windowMaxWidth窗口最大宽度,必须带单位stringnull
windowMaxHeight窗口最大高度,必须带单位stringnull
windowMinWidth窗口最小宽度,必须带单位stringnull
windowMinHeight窗口最小高度,必须带单位stringnull
maxCountWindow应用最大可打开窗口数量number1
fullScreen窗口是否全屏boolfalse
isBoxShadow是否使用用窗口阴影booltrue
isBoxShadow是否对超出窗口部分进行裁剪booltrue
isReSetSize是否可以更改窗口大小booltrue
isSizeZero窗口大小可以为0boolfalse
menu窗口启动时底部导航栏显示菜单array[]
appMenu桌面应用图标显示菜单array[]
showAddmin应用图标是否显示到应用管理界面booltrue
showDesktop应用图标是否显示到桌面booltrue
showBottomBar应用图标是否显示到底部导航栏booltrue
isCloseDestroy是否在应用应窗口全部关闭后销毁图标boolfalse

(2). 关闭窗口close、隐藏窗口hide、全屏窗口fullScreen

let appManege = this.$System.getApplicationManage();
let app = appManage.addApplicationWeb({
	title:"哔哩哔哩",
	icon:  "https://www.bilibili.com/favicon.ico?v=1",
	href :"https://www.bilibili.com/"
})

let metaWindow = app.open();
// 关闭窗口
metaWindow.close();
// 隐藏窗口
metaWindow.hide();
// 显示窗口
metaWindow.hide(false);
// 全屏窗口
metaWindow.fullScreen();
// 取消全屏窗口
metaWindow.fullScreen(false);

上面代码中的例子可以一个一个的试一下,暂时可以以定时器来进行调用。

let appManege = this.$System.getApplicationManage();
let app = appManage.addApplicationWeb({
	title:"哔哩哔哩",
	icon:  "https://www.bilibili.com/favicon.ico?v=1",
	href :"https://www.bilibili.com/"
})

let metaWindow = app.open();
// 隔2秒后关闭窗口
setTimeout(()=>{
	metaWindow.close();
},2000)

(3.) 事件Event 事件用于对窗口的一些特定的行为进行监听,如关闭窗口close、隐藏窗口hide、全屏窗口fullScreen,监听的是执行动作之前,所以可以利用这对默认行为进行拦截。

let appManege = this.$System.getApplicationManage();
let app = appManage.addApplicationWeb({
	title:"哔哩哔哩",
	icon:  "https://www.bilibili.com/favicon.ico?v=1",
	href :"https://www.bilibili.com/"
})

let metaWindow = app.open();

metaWindow.on("onClose",()=>{
	console.log("检查到窗口即将关闭");
})

metaWindow.on("onHide",({newV})=>{
	if(!newV) console.log("检查到窗口即将隐藏");
	else console.log("检查到窗口即将显示");
})

metaWindow.on("onFullScreen",({newV})=>{
	if(newV) console.log("检查到窗口即将全屏");
	else console.log("检查到窗口即将取消全屏");
})

onClose回调函数不会传递任何值,而onHide和onFullScreen会传递一个值对象,可以根据值对象里的属性newV和oldV,判断隐藏和全屏的状态。

自定义事件 如果需要自定义一个事件,可以用 emit 方法,如果你对vue熟悉,应该对emit 很熟悉。

let appManege = this.$System.getApplicationManage();
let app = appManage.addApplicationWeb({
	title:"哔哩哔哩",
	icon:  "https://www.bilibili.com/favicon.ico?v=1",
	href :"https://www.bilibili.com/"
})

let metaWindow = app.open();

// 自定义 onCloseTime 事件,事件名称可以根据自己需要定义
metaWindow.on("onCloseTime",(res)=>{
	console.log("关闭时间",res);
})

metaWindow.on("onClose",()=>{
	// 触发 onCloseTime 事件,并传递一个值
	metaWindow.emit("onCloseTime",new  Date().getTime());
})

下面,我们通过一个例子来看看创建窗口的完整流程,以及metaWindow的使用。

首先,创建一个vue组件Test.vue,放到component文件夹下面,内容如下:

<!-- Test.vue -->
<template>
	<div  class="test">
		<button @click="metaWindow.close()">关闭窗口</button>
		<button @click="metaWindow.fullScreen(true)">全屏</button>
		<button @click="metaWindow.fullScreen(false)">取消全屏</button>
		<button @click="metaWindow.hide(false)">隐藏</button>
		<button @click="metaWindow.hide(true)">取消隐藏</button>
		<button @click="metaWindow.emit('message','傻子')">自定义事件message</button>
	</div>
</template>

<script>
export  default {
	// 在此处配置窗口属性
	windowConfig:{
		windowWidth :  "600px",
		windowHeight :  "600px",
		windowTop :  "100px",
		windowLeft :  "100px",
		title:"测试",
		icon: require("@/assets/test.png")
	},
	props:["metaWindow"],// 通过props 获取到 metaWindow对象
	mounted() {
		this.metaWindow.on("onClose",()=>{
			console.log("检查到窗口即将关闭");
		})

		this.metaWindow.on("onHide",({newV})=>{
			if(!newV) console.log("检查到窗口即将隐藏");
			else console.log("检查到窗口即将显示");
		})

		this.metaWindow.on("onFullScreen",({newV})=>{
			if(newV) console.log("检查到窗口即将全屏");
			else console.log("检查到窗口即将取消全屏");
		})
		
		// 自定义事件 message
		this.metaWindow.on("message",(msg)=>{
			console.log(msg);
		})
	},
}
</script>

<style>
.test{
	width: 100%;
	height: 100%;
	background: white;
}
</style>

在app.vue中引入Test组件,并且使用Test组件

<template>
	<div  id="nav">
		<MetaDesktop/>
	</div>
</template>

<script>
import  Test from  "@/components/Test.vue"

export  default {
	data(){
		return {}
	},
mounted(){
	let app = this.$System.getApplicationManage();
	app.addApplication(Test);
}
</script>

<style>
body{
	position: relative;
	width: 100vw;
	height: 100vh;
}
#nav{
	position: relative;
	width: 100vw;
	height: 100vh;
}
</style>

然后启动项目,点击桌面上的测试图标,打开一个窗口,内容为 Test.vue 的内容,点击几个按钮,感受一下吧。

子窗口ChildMetaWindow

在浏览器里,很多时候我们页面切换的方式都是通过地址栏,然而,在Metadesktop的系统里,我们可以打开很多个功能不同的应用,它们各自有着不同的页面需要切换,这个时候,一个地址栏就不够用了。 那我们应该如何解决呢? Metadesktop的系统提供了两种方法,子窗口和页面路由,两个可以单独使用也可以混合使用,我们先来看看如何编写子窗口。

首先需要清楚的一点是,子窗口是存在于MetaWindow窗口中,我们先创建一个MetaWindow窗口。

在components文件夹下创建两个文件childWindowHome.vue和selectAddress.vue

在selectAddress.vue写入如下代码:

<template>
	<div  class="select-address">
		<ul>
			<li  v-for="item  in  addressList" :key="item" @click="select(item)">{{item}}		</li>
		</ul>
	</div>
</template>

<script>
export  default {
	childWindowConfig:{
	title:"选择地址",
	titleBarTitlePosition:"center"
	},
	inject:["childMetaWindow"],
	data() {
		return {
			addressList:["云南","贵州","广州","上海","重庆"]
		}
	},

	methods: {
		select(address){
			this.childMetaWindow.value.address = address;
			this.childMetaWindow.emit("close");
		}
	},
}
</script>

<style  scoped>
.select-address{
	width: 100%;
	height: 100%;
	background: white;
}
.select-address  ul  li{
	padding: 10px  20px;
	transition: 0.25s;
	cursor: pointer;
}
.select-address  ul  li:hover{
	background: whitesmoke;
}
</style>

在MetaWindow窗口中,使用了windowConfig来进行设置窗口属性,而在子窗口中,通过childWindowConfig来设置。

在childWindowHome.vue中写入如下代码

.<template>
	<div  class="child-window-home">
		<ul>
			<li><h3>下单确认</h3></li>
			<li><button @click="toSelectAddress">选择地址</button><p>{{address}}</p>  </li>
			<li><h5>商品列表</h5></li>
			<li><span>草莓</span><span>x1</span></li>
			<li><span>苹果</span><span>x1</span></li>
			<li><span>梨</span><span>x1</span></li>
		</ul>
	</div>
</template>

<script>
import  selectAddress  from  "@/components/selectAddress.vue";
export  default {
	windowConfig:{
	windowWidth:  "300px",
	windowHeight:  "500px",
	title:"子窗口测试",
	icon:  "",//写入自己的图片路径
},
data() {
	return {
		address:""
	}
},
inject:["System"],
mounted() {
},
methods: {
	toSelectAddress(){
		let  w = this.System.push(selectAddress,{
			address:  this.address
		}).addEvent("onClose",()=> {
			this.address = w.value.address;
		})
	}
},
}
</script>
<style  scoped>
.child-window-home{
	width: 100%;
	height: 100%;
	background: whitesmoke;
}
.child-window-home  ul  li{
	display: flex;
	padding: 5px;
}
.child-window-home  ul  li  h3{
	text-align: center;
}
.child-window-home  ul  li  span{
	width: 50%;
}
.child-window-home  ul  li  button{
	margin-right: 80px;
}
.child-window-home  ul  li >span:last-child{
	text-align: right;
}
</style>

写好了这两个文件,然后我们把 childWindowHome.vue 使用桌面图标来启动,这里就不介绍如何使用桌面图标来启动,记不得可以回去看看如何创建桌面图标的教程。

然后我们点击图标,打开 childWindowHome 组件的窗口页面,点击选择地址按钮,弹出了一个子窗口,内容是我们 selectAddress 组件中的内容,点击任意一个地址,就回到了主窗口的位置,我们可以看到,在选择按钮的右边出现了我们刚刚点击的地址,这个例子展示了如何创建子窗口、主窗口如何与子窗口通信以及如何关闭子窗口。

有了上面的例子,对子窗口就有了一定的认识,接下来我们来仔细的认识子窗口。

操作子窗口,并不需要像主窗口一样,需要获取一个管理类,而是在主窗口生成时就会自动创建一个ChildSystem 对象,这个对象通过vue的inject注入功能获取,属性名为System,要和全局的$System区分开。

export  default {
	inject:["System"],
}

ChildSystem 对象里面有五个方法push,replace,pop,back,remove用来对子窗口进行生成和删除。

应用功能管理类--ApplicationManage

我们一开始的时候已经用过该类,创建桌面图标的时候。现在我们来详细讲解一下该类。 我们知道,通过$System我们可以拿到该类的实例

const appManage = this.$System.getApplicationManage();

我们来看看它具体有哪些方法供我们使用 1. add

// add(name,icon,model, component)
// name(必须): 应用名称
// icon(必须): 应用图标
// model(必须): 模式,0-组件模式,1-web模式,2-自定义模式。组件模式可以把传入的组件渲染成窗	口,web模式把网络地址对应页面渲染成窗口,自定义模式根据自己需求进行定制
// component(可选): vue组件
// 返回值: Application对象

import Test from "@/components/Test.vue"
appManage.add('Test',require("@/assets/test.png"),Test);

如果模式为web模式或者自定义模式,请使用返回的Application对象更改。

如果是web模式,调用setValue方法设置地址、图标、标题,这几个属性是MetaWindow窗口的图标、标题,上面设置的是桌面的图标和标题

Application.setValue({
	href:'https://git-scm.com/',
	icon:'https://git-scm.com/images/logo@2x.png',
	title:'git'
});

如果是自定义模式,调用setAction,指定点击图标的回调函数

Application.setAction(()=>{
	// 点击图标需要执行的代码
});
  1. addComponent
// addComponent(component)
// component(必须): vue组件
// 返回值: Application 对象

import Test from "@/components/Test.vue"
appManage.addComponent(Test);

该方法的默认模式为0。只需要传入一个组件,所有的配置通过组件内部的windowConfg进行配置。

export  default{
	name:"Test",
	windowConfig:{
		title: "Test",
		icon: require'@/assets/test.png')
	}
}
  1. addWeb
// addWeb(value)
// value(必须): 配置:地址、图标、标题 
// 返回值: Application 对象

appManage.addWeb({
	href:'https://git-scm.com/',
	icon:'https://git-scm.com/images/logo@2x.png',
	title:'git'
});

该方法的默认模式为1 4. addCustom

// addCustom(object value,function action)
// value:一个js的数据对象,用于指定图标和名称
// action:当我们点击桌面图标时触发的函数
// 返回值: Application 对象

appManage.addCustom({
	title:"测试", 
	icon: require("@/assets/01.png") // 图标换成你自己的即可
},function(){
	console.log("我被点击了");
});

该方法的默认模式为2。

桌面背景管理类--DesktopBackgroundManage

这个类用于对桌面的背景进行设置,可以设置成纯色背景、渐变背景、图片背景、动态背景(视频背景),四种方式。 下面,我们来一一介绍这四种方式。 1. 纯色背景 首先,通过$System拿到DesktopBackgroundManage管理类

const dBManage = this.$System.DesktopBackgroundManage();

然后通过管理类里的方法setColor来设置背景色

// setColor(color)
// color: 颜色值
dBManage.setColor("pink"); // 定义自己的颜色就行

设置完颜色,我们还需要设置背景模式为纯色模式

// setModel(model)
// model: 背景模式,0:纯色模式,1:渐变模式,2:图片模式,3:动态模式
dBManage.setModel(0);

如果需要把颜色重置为默认值,可以使用defaultColor方法

// defaultColor()
dBManage.defaultColor();
  1. 渐变模式 通过管理类里的方法setRradientColor设置渐变色
// setRradientColor(angle,...color)
// angle: 渐变的角度
// ...color: 渐变的颜色,可以是一个或多个值
dBManage.setRradientColor(45,"rgb(204, 251, 255)","rgb(239, 150, 197)");

然后设置背景模式为渐变模式

// setModel(model)
// model: 背景模式,0:纯色模式,1:渐变模式,2:图片模式,3:动态模式
dBManage.setModel(1);

如果需要单独设置渐变角度,可以使用setRradientAngle方法

// setRradientAngle(angle)
// angle: 渐变的角度
dBManage.setRradientAngle(50);

如果需要把渐变色重置为默认值,可以使用defaultRradientColor方法

// defaultRradientColor()
dBManage.defaultRradientColor();
  1. 图片背景 需要使用pushImage方法将图片路径加入图片管理数组中
// pushImage(src)
// src: 图片路径
dBManage.pushImage(require'@/assets/bg.jpg'))

加入后把背景模式设置为图片模式

// setModel(model)
// model: 背景模式,0:纯色模式,1:渐变模式,2:图片模式,3:动态模式
dBManage.setModel(2);

因为图片可能有很多张,可以使用setImageIndex方法进行图片切换

// setImageIndex(index)
// index: 图片在数组中的索引
dBManage.setImageIndex(1);

有的时候,需要清空图片数组,可以使用clearImage方法

// clearImage()
dBManage.clearImage()

如果需要把重置图片设置,可以使用defaultImage方法

// defaultImage()
dBManage.defaultImage();
  1. 动态背景 需要使用pushVideo方法将图片路径加入图片管理数组中
// pushVideo(src)
// src: 视频路径
dBManage.pushVideo(require'@/assets/bg.MP4'))

加入后把背景模式设置为动态模式

// setModel(model)
// model: 背景模式,0:纯色模式,1:渐变模式,2:图片模式,3:动态模式
dBManage.setModel(3);

因为视频可能有很多,可以使用setVideoIndex方法进行图片切换

// setVideoIndex(index)
// index: 视频在数组中的索引
dBManage.setVideoIndex(1);

有的时候,需要清空视频数组,可以使用clearVideo方法

// clearVideo()
dBManage.clearVideo()

如果需要把重置动态设置,可以使用defaultVideo方法

// defaultVideo()
dBManage.defaultVideo();

底部导航栏管理类--BottomBarManage

需要通过$system中的getBottomBarManage方法获取该类。这个类可以更改底部导航栏的背景色、激活图标背景色。 1. setBackground

// 修改背景色
// setBackground(color)
// color: 需要设置的颜色

const bottomBarManage = this.$System.getBottomBarManage();

bottomBarManage.setBackground("#fff");
  1. setIconBackground
// 修改激活图标背景色
// setIconBackground(color)
// color: 需要设置的颜色

const bottomBarManage = this.$System.getBottomBarManage();

bottomBarManage.setIconBackground("#fff");

如果需要对设置进行恢复默认值,可以使用defaultSetting方法

// 恢复默认值
// defaultSetting()

const bottomBarManage = this.$System.getBottomBarManage();

bottomBarManage.defaultSetting();

系统通知管理类--NoticeManage

在MetaDesktop的右下角,有一个留言样式的图标,我们点击它,会弹出一个窗口,而NoticeManage类就是用来操作该窗口。这个类能操作的有三个方法setBackground、add和close。setBackground用来改变窗口的背景色,而add是用来添加一条通知,添加通知需要一个通知组件模板,close用来移除通。通过$System 的getNoticeManage方法获取该管理类 1. setBackground

// setBackground(color)
// color: 颜色

const noticeManage= this.$System.getNoticeManage();

noticeManage.setBackground("#00ff00");
  1. add
// add(value,component)
// value: 需要传递到模板中的值
// component: 组件模板,默认值为内置的一个通知模板,需要传递title和msg
// 返回值:id,通知唯一标识id

const noticeManage= this.$System.getNoticeManage();

noticeManage.add({
	title:"重要提醒!",
	msg:"数据库v那就是看到女"
});

在模板组件内使用props来获取传递的value值

export  default {
	props:["value"]
}
  1. close 添加了通知,close函数把通知从通知列表里移除,close需要传递一个id值,这个id是add的时候返回的。
// close(id)
// id: 通知唯一标识id

const noticeManage= this.$System.getNoticeManage();
let id = noticeManage.add({
	title:"重要提醒!",
	msg:"数据库v那就是看到女"
});

//隔5s关闭该条通知
setTimeout(()=>{
	noticeManage.close(id);
},5000)

在模板组件内部,可以通过props和inject获取id和close函数

export  default {
	props:["value","id"],
	inject:["close"],
}

联系方式

邮件:webappmall@163.com

0.1.3

12 months ago

0.1.0

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.0.7-1

2 years ago

0.0.5-3

2 years ago

0.0.6-1

2 years ago

0.0.7-5

1 year ago

0.0.7-4

1 year ago

0.0.5-6

2 years ago

0.0.7-3

1 year ago

0.0.5-5

2 years ago

0.0.7-2

2 years ago

0.0.5-4

2 years ago

0.0.7

2 years ago

0.0.7-6

1 year ago

0.0.6

2 years ago

0.0.5-2

2 years ago

0.0.5-1

2 years ago

0.0.5-0

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago