1.0.0-coordinate • Published 6 days ago

@heycar/heycars-map v1.0.0-coordinate

Weekly downloads
-
License
-
Repository
-
Last release
6 days ago

说明

时间关系,先写个简要文档,之后会补一个全面的文档。

特性

  • 集成 高德 和 谷歌 两个地图
  • 支持 vue 2.7 和 vue 3
  • 统一的接口,不需要写两套

安装

# 安装依赖包
npm install @heycar/heycars-map --save

加载地图样式

import "@heycar/heycars-map/dist/style.css";

自定义字体

目前地图提供了 3 个字体 css variables 用于外部制定特殊字体

/* 使用特殊字体 HarmonyOS_Sans_SC_Regular */
body {
  --HEYCAR_MAP_CSS_VAR_FONT_REGULAR: HarmonyOS_Sans_SC_Regular, "PingFangSC-Regular", "PingFang SC";
  --HEYCAR_MAP_CSS_VAR_FONT_MEDIUM: HarmonyOS_Sans_SC_Medium, "PingFangSC-Medium", "PingFang SC";
  --HEYCAR_MAP_CSS_VAR_FONT_SEMI_BOLD: HarmonyOS_Sans_SC_Bold, "PingFangSC-Semibold", "PingFang SC";
}

使用

常用数据结构

export type CoordinateType = "wgs84" | "gcj02" | "bd09";

export type CoordinatePoint = {
  lng: number;
  lat: number;
  type: CoordinateType;
};

export type CoordinatePlace = {
  lng: number;
  lat: number;
  type: CoordinateType;
  name: string;
  displayName: string;
};

export interface CoordinateZone {
  name: string;
  path: CoordinatePoint[];
}

export interface CoordinateRecommendZonePlaces {
  // 是否强制吸附
  adsorption?: boolean;
  // 是否强制推荐点
  force?: boolean;
  // 是否可以提供服务
  available?: boolean;
  zone?: CoordinateZone;
  places?: CoordinatePlace[];
}

export interface CoordinateGeoPosition {
  position: CoordinatePoint;
  coords?: GeolocationCoordinates;
}

export interface CoordinateTrackPoint {
  lng: number;
  lat: number;
  type: CoordinateType;
  angle?: number;
  speed?: number;
  timestamp: number;
}

export enum CenterPlaceStatus {
  GEO_LOADING = "GEO_LOADING",
  QUERYING_INFO = "QUERYING_INFO",
  SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",
  OK = "OK",
}

在 入口文件添加 MapProvider

  • 对于 jsx/tsx 文件的例子
<MapProvider
  // 高德地图 api key
  amapKey={amapApiKey}
  // 高德地图 secret
  amapSecret={amapApiSecret}
  // 谷歌地图 id
  gmapId={gmapId}
  // 谷歌地图 api key
  gmapKey={gmapApiKey}
  // 使用哪个地图供应商,目前两个供应商: amap 高德 / gmap 谷歌
  supplier={"amap"}
>
  ...
</MapProvider>
  • 对于 vue 文件的例子
<MapProvider
  :gmap-id="gmapId"
  :gmap-key="gmapApiKey"
  :amap-key="amapApiKey"
  :amap-secret="amapApiSecret"
  supplier="amap"
>
   ...
</MapProvider>

在地图里可以使用的组件

为了方便集成,已经将常用业务逻辑集成在四个业务组件里面,下面是推荐使用的业务组件

  • BusinessRecomendPlaceMap
  • BusinessReselectPlaceMap
  • BusinessQuotingMap
  • BusinessTaxiServiceMap
  • BusinessTaxiEndMap

下面三个是推荐搭配使用的业务 hooks

  • useBusinessRecomendPlaceMap
  • useBusinessReselectPlaceMap
  • useBusinessQuotingMap
  • useBusinessTaxiServiceMap

选择上车点和推荐点的地图组件 BusinessRecomendPlaceMap

对于 jsx/tsx 文件的例子

import { defineComponent } from "vue";
import { BusinessRecomendPlaceMap, useBusinessRecomendPlaceMap } from "@heycar/heycars-map";

export default defineComponent({
  setup() {
    const {
      centerPlace,
      mapContext,
      setCenterPlaceByUserSpecified,
      setCenterPlaceByUserSpecifiedInZone,
    } = useBusinessRecomendPlaceMap();
    // 演示 setCenterPlaceByUserSpecifiedInZone 的用法
    const demoForUsage = () => {
      setCenterPlaceByUserSpecifiedInZone({
        // 期望的地图中心点
        place: {
          lng: 139.56,
          lat: 35.56,
          type: "gcj02",
          name: "user specified place in zone",
          displayName: "user specified place in zone",
        },
        // 推荐点和绿区信息
        recommends: {
          // 绿区
          zone: {
            name: "zone 1",
            path: [
              { lng: 139.569, lat: 35.555, type: "gcj02" },
              { lng: 139.558, lat: 35.55, type: "gcj02" },
              { lng: 139.56, lat: 35.565, type: "gcj02" },
            ],
          },
          // 绿区内的推荐点列表
          places: [
            {
              lng: 139.56,
              lat: 35.56,
              type: "gcj02",
              name: "user specified place in zone",
              displayName: "user specified place in zone",
            },
            {
              lng: 139.562,
              lat: 35.562,
              type: "gcj02",
              name: "recommend place 2",
              displayName: "recommend place 2",
            },
          ],
        },
      });
    };
    return () => (
      <BusinessRecomendPlaceMap
        class={"demo"}
        geoLoadingTitle={"正在获取您当前的位置"}
        unavailableTitle={"当前区域暂未开通服务"}
        emptyTitle={"当前位置"}
        queryingTitle={"正在获取地址信息"}
        recomendDescription={"您将在此处上车"}
        geoErrorOnceNotificationKey="BusinessReselectPlaceMap_GeoErrorOnceKey"
        defaultCenterPlace={(place) =>
          place ?? {
            lng: 139.777777,
            lat: 35.777777,
            type: "gcj02",
            name: "default place name",
            displayName: "default place displayName",
          }
        }
        getAvailable={() => Promise.resolve(true)}
        getRecomendPlace={getRecomendPlace}
        getDefaultCenterPlace={getDefaultCenterPlace}
        renderPlacePhoto={(place) => {
          place;
          return "https://oss-now.heycars.cn/image/graphicGuidance/file/hmlh38_xs6_DdksNX0_TbgF0lKXp.jpg";
        }}
        renderPlaceTag={(place) => {
          place;
          return "最近使用";
        }}
        mapContext={mapContext}
        onChangePlace={(place) => {
          console.log("地图中心点变化时触发 place = ", place);
        }}
        onChangeRecomandPlace={({ place, inputPlace, isInZone }) => {
          console.log("用户操作地图,计算推荐点后得出的最终位置时触发,此时可以向后端查询城市信息");
          console.log(
            "计算推荐点之前的地址是: ",
            inputPlace,
            " 最终的地址是: ",
            place,
            " 是否在绿区内: ",
            isInZone,
          );
        }}
        onClickLocatorText={() =>
          console.log("用户点击了蓝色光标文字触发,此时可以执行用户点击起点输入框相同的逻辑")
        }
        onClickLocatorPhoto={() =>
          console.log("用户点击了蓝色光标图片触发,此时可以执行用户点击起点输入框相同的逻辑")
        }
        onGeoError={() => {
          console.log("获取GPS失败时触发,此时可以弹框告诉用户");
        }}
        onGeoErrorOnce={(isBusinessTimeout) => {
          console.log(
            "获取GPS失败时触发, 只触发一次, ",
            isBusinessTimeout ? "给用户超时提示" : "给用户无权限反馈",
          );
        }}
      />
    );
  },
});

选择上车点和推荐点的地图组件 BusinessReselectPlaceMap

对于 jsx/tsx 文件的例子

import { defineComponent } from "vue";
import { BusinessReselectPlaceMap, useBusinessReselectPlaceMap } from "@heycar/heycars-map";

export default defineComponent({
  setup() {
    const {
      centerPlace,
      mapContext,
      setCenterPlaceByUserSpecified,
      setCenterPlaceByUserSpecifiedInZone,
    } = useBusinessReselectPlaceMap();
    // 演示 setCenterPlaceByUserSpecifiedInZone 的用法
    const demoForUsage = () => {
      setCenterPlaceByUserSpecifiedInZone({
        // 期望的地图中心点
        place: {
          lng: 139.56,
          lat: 35.56,
          type: "gcj02",
          name: "user specified place in zone",
          displayName: "user specified place in zone",
        },
        // 推荐点和绿区信息
        recommends: {
          // 绿区
          zone: {
            name: "zone 1",
            path: [
              { lng: 139.569, lat: 35.555, type: "gcj02" },
              { lng: 139.558, lat: 35.55, type: "gcj02" },
              { lng: 139.56, lat: 35.565, type: "gcj02" },
            ],
          },
          // 绿区内的推荐点列表
          places: [
            {
              lng: 139.56,
              lat: 35.56,
              type: "gcj02",
              name: "user specified place in zone",
              displayName: "user specified place in zone",
            },
            {
              lng: 139.562,
              lat: 35.562,
              type: "gcj02",
              name: "recommend place 2",
              displayName: "recommend place 2",
            },
          ],
        },
      });
    };
    return () => (
      <BusinessReselectPlaceMap
        class={"demo"}
        unavailableTitle={"当前区域暂未开通服务"}
        emptyTitle={"当前位置"}
        queryingTitle={"正在获取地址信息"}
        recomendDescription={"您将在此处上车"}
        // 对于同一个 geoErrorOnceNotificationKey
        // geoErrorOnce 事件在 geoErrorOnceNotificationInterval 时间间隔内全局只会触发一次
        geoErrorOnceNotificationKey="BusinessReselectPlaceMap"
        defaultPlace={{
          lng: 139.777777,
          lat: 35.777777,
          type: "gcj02",
          name: "default place name",
          displayName: "default place display name",
        }}
        getAvailable={() => Promise.resolve(true)}
        getRecomendPlace={async ({ lng, lat, type }) => {
          // 向后端获取推荐点信息
          return {
            // 服务是否可用
            available: true,
            // 绿区
            zone: {
              name: "绿区名称",
              path: [
                { lng: lng - 0.001, lat: lat + 0.001, type },
                { lng: lng, lat: lat - 0.001, type },
                { lng: lng + 0.001, lat: lat + 0.0005, type },
              ],
            },
            // 推荐点列表
            places: [
              {
                lat: lat - 0.00001,
                lng: lng + 0.0001,
                type,
                name: "place 1",
                displayName: "place 1",
              },
              {
                lat: lat - 0.0002,
                lng: lng + 0.0002,
                type,
                name: "place 2",
                displayName: "place 2",
              },
              {
                lat: lat - 0.0002,
                lng: lng - 0.0001,
                type,
                name: "place 3",
                displayName: "place 3",
              },
            ],
          };
        }}
        onChangeRecomandPlace={({ place, inputPlace, isInZone }) => {
          console.log("用户操作地图,计算推荐点后得出的最终位置时触发,此时可以向后端查询城市信息");
          console.log(
            "计算推荐点之前的地址是: ",
            inputPlace,
            " 最终的地址是: ",
            place,
            " 是否在绿区内: ",
            isInZone,
          );
        }}
        onClickLocatorText={() =>
          console.log("用户点击了蓝色光标文字触发,此时可以执行用户点击起点输入框相同的逻辑")
        }
        onClickLocatorPhoto={() =>
          console.log("用户点击了蓝色光标图片触发,此时可以执行用户点击起点输入框相同的逻辑")
        }
        onGeoError={() => {
          console.log("获取GPS失败时触发,此时可以弹框告诉用户");
        }}
        onGeoErrorOnce={(isBusinessTimeout) => {
          console.log(
            "获取GPS失败时触发, 只触发一次, ",
            isBusinessTimeout ? "给用户超时提示" : "给用户无权限反馈",
          );
        }}
      />
    );
  },
});

询价业务的地图组件 BusinessQuotingMap

对于 jsx/tsx 文件的例子

import { defineComponent } from "vue";
import { BusinessQuotingMap, useBusinessQuotingMap } from "@heycar/heycars-map";

export default defineComponent({
  setup() {
    const { setMap, registerFitVeiw } = useBusinessQuotingMap();
    return () => (
      <BusinessQuotingMap
        class={"demo"}
        from={{
          displayName: "The Malayan Council",
          name: "10 Winstedt Rd, #01-17, Singapore 227977",
          type: "wgs84",
          lat: 1.311295,
          lng: 103.841974,
        }}
        to={{
          displayName: "CDG Engie Charging Station",
          name: "21 Kent Ridge Rd, Singapore 119220",
          type: "wgs84",
          lat: 1.2966426,
          lng: 103.7763939,
        }}
        fromDescription={"您将在此上车"}
        renderDescription={({ distance, duration, tolls }) =>
          `全程 *${distance / 1000}公里*  约行驶 *${duration}* 高速费用 *${tolls ?? 0}*元`
        }
        mapRef={setMap}
        registerOverlay={registerFitVeiw}
        onClickStartPoint={(place) => console.log("点击起点时触发 palce = ", place)}
        onClickEndPoint={(place) => console.log("点击终点时触发 palce = ", place)}
      />
    );
  },
});

打车状态流转业务的地图组件 BusinessTaxiServiceMap

对于 jsx/tsx 文件的例子

import { defineComponent } from "vue";
import { BusinessTaxiServiceMap, useBusinessTaxiServiceMap } from "@heycar/heycars-map";

export default defineComponent({
  setup() {
    const { setMap, registerFitVeiw } = useBusinessTaxiServiceMap();
    return () => (
      <BusinessTaxiServiceMap
        class={css.adjustedDemo}
        from={{
          displayName: "The Malayan Council",
          name: "10 Winstedt Rd, #01-17, Singapore 227977",
          type: "wgs84",
          lat: 1.311295,
          lng: 103.841974,
        }}
        to={{
          displayName: "CDG Engie Charging Station",
          name: "21 Kent Ridge Rd, Singapore 119220",
          type: "wgs84",
          lat: 1.2966426,
          lng: 103.7763939,
        }}
        driverStatus={"driverArrived"}
        bookDispatchingTitle="2月14日 11:00 用车"
        dispatchingTitle="正在为您搜索附近司机"
        driverArrivedTitle="司机已等待 00:35"
        renderStartSerivceTitle={({ distance, duration }) =>
          `距你*${distance}*公里, *${duration}*分钟`
        }
        renderInServiceTitle={({ distance, duration }) =>
          `距离终点*${distance}*公里, 预计*${duration}*分钟`
        }
        getDriverPositionTrack={async () => {
          //  向后端请求司机的历史轨迹
          return Promise.resolve<TrackPoint[]>([
            { lng: 121.4036983, lat: 31.216324, type: "gcj02", angle: 30, timestamp: 1698058438000 },
            { lng: 121.4036983, lat: 31.216324, type: "gcj02", angle: 30, timestamp: 1698058439000 },
            { lng: 121.403581, lat: 31.216415, type: "gcj02", angle: 30, timestamp: 1698058442000 },
          ]);
        }}
        interval={5000}
        mapRef={setMap}
        registerOverlay={registerFitVeiw}
      />
    );
  },
});

服务结束的地图组件

对于 jsx/tsx 文件的例子

import { defineComponent } from "vue";
import { BusinessTaxiEndMap } from "@heycar/heycars-map";

export default defineComponent({
  setup() {
    return () => (
      <BusinessTaxiEndMap
        class={"demo"}
        from={{
          displayName: "樟宜机场",
          name: "樟宜机场",
          lat: 1.35019,
          lng: 103.994003,
          type: "wgs84",
        }}
        to={{
          lat: 1.346493,
          lng: 103.746209,
          name: "长城美华 Coffee Shop (CCMW)",
          displayName: "长城美华 Coffee Shop (CCMW)",
          type: "wgs84",
        }}
      />
    );
  },
});

下面是基础业务组件的使用方法,但是目前阶段不推荐使用

下列是一些更加基础的业务组件, 虽然导出了,但是目前阶段不推荐使用

  • AbsoluteAddressBox
  • DrivingLine
  • PassengerCircle
  • PlaceCircle
  • StartEndPoint
  • TaxiCar
  • WalkingLine
  • WaveCircle
  • DrivingRoute
  • WalkingRoute
  • PickupPoints

在地图里使用 AddressBox ,需要放在 HeycarMap 内部

<HeycarMap center={[0, 0]} zoom={3}>
  ...
  <AddressBox position={[0, 0]} title={"Martyrs Lawn"} description={"您将在此处上车"} />
  ...
</HeycarMap>
  • 对于 vue 文件的例子
<HeycarMap :center="[0, 0]" class="any class name" :zoom="3">
   <template #fallback>error</template>
   <template #loading>loading</template>
   ...
   <AddressBox title="Martyrs Lawn" :position="[0, 0]" description="您将在此处上车" >
   </AddressBox>
   ...
</HeycarMap>

HeycarMap 的基本用法

  • 对于 jsx/tsx 文件的例子
<HeycarMap
  class="any class name"
  // 地图加载失败要显示的内容
  fallback={() => <div>error</div>}
  // 地图还没有加载完成时要显示的内容
  loading={() => <div>loading</div>}
  // 地图中心点
  center={[0, 0]}
  // 地图放缩
  zoom={3}
>
  ...
</HeycarMap>
  • 对于 vue 文件的例子
<HeycarMap :center="[0, 0]" class="any class name" :zoom="3">
   <template #fallback>error</template>
   <template #loading>loading</template>
   ...
</HeycarMap>

关于 enableAuxiliaryGraspRoad 模式

enableAuxiliaryGraspRoad 模式适用场景:

  • 测试司机位置偏移 的优化效果
  • 目前只能在国内打车,测试优化效果。
  • 目前只能用 splytech 供应商进行测试。

测试时的注意点:

  1. 起点和终点 在 splytech 后台系统地图上的位置是错误的。

为了方便测试 司机位置偏移 的优化效果,在 enableAuxiliaryGraspRoad 模式下会显示下列辅助信息:

  1. 会显示两个导航路线,蓝色跟设计稿样式一致的是原来的导航路径,红色的是司机位置纠偏以后计算的导航路径。
  2. 会显示两个车辆,跟设计稿样式一致的是原来的车辆,虚影的车辆是司机位置纠偏以后的车辆。
  3. 会将供应商提供的司机位置显示为蓝色标记,辅助观察供应商提供的司机位置。
  4. 会显示一条黑色的路径,表示将供应商提供的位置纠偏以后的路径。
  5. enableAuxiliaryGraspRoad 模式下,为了方便测试,取消了屏幕 15 秒自动调整功能。
0.12.0-snapRoad1

12 days ago

0.11.0-google3

17 days ago

0.11.0-google1

20 days ago

0.11.0-google2

20 days ago

0.10.0-7-vue

27 days ago

0.10.0-6-vue

1 month ago

0.10.0-1-vue

1 month ago

0.10.0-2-vue

1 month ago

0.10.0-5-vue

1 month ago

0.10.0-4-vue

1 month ago

0.10.0-3-vue

1 month ago

0.9.27-google9

2 months ago

0.9.27-google8

2 months ago

0.9.27-google7

2 months ago

0.9.27-google6

2 months ago

0.9.27-google5

2 months ago

0.9.27-google4

2 months ago

0.9.27-google3

2 months ago

0.9.27-google2

2 months ago

0.9.27-google1

2 months ago

0.9.26-wxsign1

4 months ago

0.9.25-alpha3

4 months ago

0.9.25-alpha2

4 months ago

0.9.25-alpha1

4 months ago

0.9.24-alpha4

5 months ago

0.9.24-alpha3

5 months ago

0.9.24-alpha2

5 months ago

0.9.24-alpha1

5 months ago

0.9.23-alpha12

5 months ago

0.9.23-alpha11

5 months ago

0.9.23-alpha10

5 months ago

0.9.23-alpha9

5 months ago

0.9.23-alpha8

5 months ago

0.8.9

9 months ago

0.8.8

9 months ago

0.8.5

9 months ago

0.8.4

9 months ago

0.8.7

9 months ago

0.8.6

9 months ago

0.9.20-timeout4

6 months ago

0.9.20-timeout3

6 months ago

0.9.20-timeout2

6 months ago

0.9.20-timeout1

6 months ago

0.9.15-os38-0

8 months ago

0.9.22-photo

6 months ago

0.7.2

10 months ago

0.7.1

10 months ago

0.7.3

10 months ago

0.10.0-graspRoad3

8 months ago

0.10.0-graspRoad4

7 months ago

0.10.0-graspRoad2

8 months ago

0.9.8

8 months ago

0.7.11

9 months ago

0.9.7

8 months ago

0.7.10

9 months ago

0.9.9

8 months ago

0.9.4

8 months ago

0.9.3

8 months ago

0.9.6

8 months ago

0.9.5

8 months ago

0.9.20-timeout

6 months ago

0.9.21-alpha2

6 months ago

0.9.23-alpha3

5 months ago

0.7.7-animate1

10 months ago

0.9.23-alpha4

5 months ago

0.9.23-alpha1

5 months ago

0.9.23-alpha2

5 months ago

0.7.7-animate2

10 months ago

0.7.4-zone2

10 months ago

0.9.22-photo11

5 months ago

0.9.21-alpha

6 months ago

0.7.4-zone3

10 months ago

0.7.4-zone4

9 months ago

0.9.23-alpha7

5 months ago

0.9.23-alpha5

5 months ago

0.9.23-alpha6

5 months ago

0.9.21-alpha3

6 months ago

0.8.1

9 months ago

0.9.21-alpha4

6 months ago

0.8.0

9 months ago

0.9.21-alpha5

6 months ago

0.8.3

9 months ago

0.9.21-alpha6

6 months ago

0.8.2

9 months ago

0.9.22-photo10

5 months ago

0.7.4-zone1

10 months ago

0.9.12

8 months ago

0.9.13

8 months ago

0.9.14

8 months ago

0.9.15

8 months ago

0.9.10

8 months ago

0.9.11

8 months ago

0.9.16

7 months ago

0.9.17

7 months ago

0.9.19

6 months ago

0.9.18-graspRoad

6 months ago

0.10.0-graspRoad

8 months ago

0.9.20-querying

6 months ago

0.9.18-graspRoad2

6 months ago

0.9.8-fix2

8 months ago

0.9.8-fix1

8 months ago

0.9.22-photo7

6 months ago

0.9.0

9 months ago

0.9.22-photo6

6 months ago

0.9.22-photo5

6 months ago

0.9.22-photo4

6 months ago

0.9.1

9 months ago

0.9.22-photo3

6 months ago

0.9.8-memory

8 months ago

0.9.22-photo2

6 months ago

0.7.6

10 months ago

0.7.5

10 months ago

0.9.22-photo9

5 months ago

0.7.8

10 months ago

0.9.8-memory3

8 months ago

0.9.8-memory4

8 months ago

0.9.8-memory2

8 months ago

0.8.11

9 months ago

0.9.20-querying2

6 months ago

0.9.20-querying3

6 months ago

0.8.10

9 months ago

0.9.19-graspRoad4

6 months ago

0.9.19-graspRoad3

6 months ago

0.9.19-graspRoad2

6 months ago

0.9.19-graspRoad

6 months ago

0.9.19-graspRoad6

6 months ago

0.9.19-graspRoad5

6 months ago

0.7.0

10 months ago

0.6.7

12 months ago

0.6.6

12 months ago

0.6.9

12 months ago

0.6.8

12 months ago

0.6.10

11 months ago

0.6.11

11 months ago

0.6.3

1 year ago

0.6.2

1 year ago

0.6.5

12 months ago

0.6.4

12 months ago

0.4.9

1 year ago

0.4.8

1 year ago

0.2.12

1 year ago

0.2.11

1 year ago

0.2.10

1 year ago

0.3.0

1 year ago

0.3.18

1 year ago

0.5.4

1 year ago

0.3.6

1 year ago

0.5.3

1 year ago

0.3.5

1 year ago

0.5.6

1 year ago

0.3.8

1 year ago

0.5.5

1 year ago

0.3.7

1 year ago

0.5.0

1 year ago

0.3.2

1 year ago

0.3.1

1 year ago

0.5.2

1 year ago

0.3.4

1 year ago

0.5.1

1 year ago

0.3.3

1 year ago

0.5.8

1 year ago

0.5.7

1 year ago

0.3.9

1 year ago

0.5.9

1 year ago

0.3.17

1 year ago

0.3.16

1 year ago

0.3.15

1 year ago

0.3.13

1 year ago

0.3.10

1 year ago

0.4.5

1 year ago

0.4.4

1 year ago

0.4.7

1 year ago

0.2.9

1 year ago

0.4.6

1 year ago

0.4.1

1 year ago

0.4.0

1 year ago

0.6.1

1 year ago

0.4.3

1 year ago

0.6.0

1 year ago

0.4.2

1 year ago

0.2.8

1 year ago

0.2.7

1 year ago

0.2.6

1 year ago

0.2.5

1 year ago

0.2.4

1 year ago

0.2.3

1 year ago

0.2.2

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.9

1 year ago

0.1.8

1 year ago

0.1.7

1 year ago

0.1.6

1 year ago

0.1.5

1 year ago

0.1.4

1 year ago

0.1.3

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago