Skip to content

Commit

Permalink
Merge pull request #73 from SylarLong/v1.3.4
Browse files Browse the repository at this point in the history
refactor code
  • Loading branch information
SylarLong authored Oct 22, 2023
2 parents 40b0008 + 3145f05 commit af266ab
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 188 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@
- 🛠️ 修复(fix)
- 🧹 琐事(Chore)

## v1.3.4

- ✨ 改进(enhancement)

🇨🇳

- 重构代码 #72

🇺🇸

- refactor code #72

- 🛠️ 修复(fix)

🇨🇳

- 文曲星亮度丢失

🇺🇸

- fix brightness missed issue

## v1.3.3

- 🪄 功能(feature)
Expand Down
12 changes: 10 additions & 2 deletions src/__tests__/astro/astro.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ describe('Astrolabe', () => {
expect(horoscope.decadal).toHaveProperty('index', 2);
expect(horoscope.decadal).toHaveProperty('heavenlyStem', '경');
expect(horoscope.decadal).toHaveProperty('earthlyBranch', '진');
expect(horoscope.decadal.stars).toStrictEqual([
expect(
horoscope.decadal?.stars?.map((stars) =>
stars.map((star) => ({ name: star.name, type: star.type, scope: star.scope })),
),
).toStrictEqual([
[{ name: '천마(십년)', type: 'tianma', scope: 'decadal' }],
[{ name: '문곡(십년)', type: 'soft', scope: 'decadal' }],
[],
Expand Down Expand Up @@ -278,7 +282,11 @@ describe('Astrolabe', () => {
expect(horoscope.yearly).toHaveProperty('index', 1);
expect(horoscope.yearly).toHaveProperty('heavenlyStem', '계');
expect(horoscope.yearly).toHaveProperty('earthlyBranch', '묘');
expect(horoscope.yearly.stars).toStrictEqual([
expect(
horoscope.yearly?.stars?.map((stars) =>
stars.map((star) => ({ name: star.name, type: star.type, scope: star.scope })),
),
).toStrictEqual([
[],
[
{ name: '천괴(년)', type: 'soft', scope: 'yearly' },
Expand Down
36 changes: 32 additions & 4 deletions src/__tests__/star/star.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,17 @@ describe('star/index', () => {
});

test('getMajorStar()', () => {
expect(getMajorStar('2023-03-06', 4, true)).toStrictEqual([
expect(
getMajorStar('2023-03-06', 4, true)?.map((stars) =>
stars.map((star) => ({
name: star.name,
type: star.type,
scope: star.scope,
brightness: star.brightness,
mutagen: star.mutagen,
})),
),
).toStrictEqual([
[{ name: '七杀', type: 'major', brightness: '庙', scope: 'origin', mutagen: '' }],
[{ name: '天同', type: 'major', brightness: '平', scope: 'origin', mutagen: '' }],
[{ name: '武曲', type: 'major', brightness: '庙', scope: 'origin', mutagen: '' }],
Expand All @@ -163,7 +173,17 @@ describe('star/index', () => {
test('getMajorStar() vi-VN', () => {
setLanguage('vi-VN');

expect(getMajorStar('2023-03-06', 4, true)).toStrictEqual([
expect(
getMajorStar('2023-03-06', 4, true)?.map((stars) =>
stars.map((star) => ({
name: star.name,
type: star.type,
scope: star.scope,
brightness: star.brightness,
mutagen: star.mutagen,
})),
),
).toStrictEqual([
[{ name: 'Thất Sát', type: 'major', brightness: 'Miếu', scope: 'origin', mutagen: '' }],
[{ name: 'Thiên Đồng', type: 'major', brightness: 'Bình', scope: 'origin', mutagen: '' }],
[{ name: 'Vũ Khúc', type: 'major', brightness: 'Miếu', scope: 'origin', mutagen: '' }],
Expand Down Expand Up @@ -260,7 +280,11 @@ describe('star/index', () => {
});

test('getHoroscopeStar() scope="decadal"', () => {
expect(star.getHoroscopeStar('庚', '辰', 'decadal')).toStrictEqual([
expect(
star
.getHoroscopeStar('庚', '辰', 'decadal')
?.map((stars) => stars.map((star) => ({ name: star.name, type: star.type, scope: star.scope }))),
).toStrictEqual([
[{ name: '运马', type: 'tianma', scope: 'decadal' }],
[{ name: '运曲', type: 'soft', scope: 'decadal' }],
[],
Expand All @@ -283,7 +307,11 @@ describe('star/index', () => {
});

test('getHoroscopeStar() scope="yearly"', () => {
expect(star.getHoroscopeStar('癸', '卯', 'yearly')).toStrictEqual([
expect(
star
.getHoroscopeStar('癸', '卯', 'yearly')
?.map((stars) => stars.map((star) => ({ name: star.name, type: star.type, scope: star.scope }))),
).toStrictEqual([
[],
[
{ name: '流魁', type: 'soft', scope: 'yearly' },
Expand Down
15 changes: 4 additions & 11 deletions src/astro/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,14 @@ import {
solar2lunar,
} from '../calendar';
import { CHINESE_TIME, EARTHLY_BRANCHES, HEAVENLY_STEMS, TIME_RANGE, earthlyBranches } from '../data';
import { Language, Star } from '../data/types';
import { Language } from '../data/types';
import { EarthlyBranchKey, EarthlyBranchName, GenderName, HeavenlyStemKey, kot, setLanguage, t } from '../i18n';
import { getAdjectiveStar, getBoShi12, getchangsheng12, getMajorStar, getMinorStar, getYearly12 } from '../star';
import FunctionalStar from '../star/FunctionalStar';
import { fixIndex } from '../utils';
import FunctionalAstrolabe from './FunctionalAstrolabe';
import FunctionalPalace, { IFunctionalPalace } from './FunctionalPalace';
import { getPalaceNames, getSoulAndBody, getHoroscope, getFiveElementsClass } from './palace';

const _toFunctionalStars = (stars: Star[]) => {
return stars.map((star) => new FunctionalStar(star));
};

/**
* 通过阳历获取星盘信息
*
Expand Down Expand Up @@ -73,11 +68,9 @@ export const astrolabeBySolarDate = (
earthlyBranchOfPalace === earthlyBranchOfYear,
heavenlyStem: t(heavenlyStemOfPalace),
earthlyBranch: t(earthlyBranchOfPalace),
majorStars: _toFunctionalStars(
majorStars[i].concat(minorStars[i].filter((star) => ['lucun', 'tianma'].includes(star.type))),
),
minorStars: _toFunctionalStars(minorStars[i].filter((star) => !['lucun', 'tianma'].includes(star.type))),
adjectiveStars: _toFunctionalStars(adjectiveStars[i]),
majorStars: majorStars[i].concat(minorStars[i].filter((star) => ['lucun', 'tianma'].includes(star.type))),
minorStars: minorStars[i].filter((star) => !['lucun', 'tianma'].includes(star.type)),
adjectiveStars: adjectiveStars[i],
changsheng12: changsheng12[i],
boshi12: boshi12[i],
jiangqian12: jiangqian12[i],
Expand Down
2 changes: 1 addition & 1 deletion src/data/stars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const STARS_INFO = {
wenchangMin: {
brightness: ['xian', 'li', 'de', 'miao', 'xian', 'li', 'de', 'miao', 'xian', 'li', 'de', 'miao'],
},
wenjuMin: {
wenquMin: {
brightness: ['ping', 'wang', 'de', 'miao', 'xian', 'wang', 'de', 'miao', 'xian', 'wang', 'de', 'miao'],
},
huoxingMin: {
Expand Down
4 changes: 2 additions & 2 deletions src/data/types/astro.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IFunctionalPalace } from '../../astro/FunctionalPalace';
import { EarthlyBranchName, FiveElementsClassName, HeavenlyStemName, PalaceName, StarName } from '../../i18n';
import FunctionalStar from '../../star/FunctionalStar';
import { HeavenlyStemAndEarthlyBranchDate, LunarDate } from './calendar';
import { Star } from './star';

/**
* 运限对象
Expand All @@ -27,7 +27,7 @@ export type HoroscopeItem = {
/** 四化星 */
mutagen: StarName[];
/** 流耀 */
stars?: Star[][];
stars?: FunctionalStar[][];
};

/**
Expand Down
87 changes: 50 additions & 37 deletions src/star/adjectiveStar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { initStars } from '.';
import { getHeavenlyStemAndEarthlyBranchBySolarDate } from '../calendar';
import { t } from '../i18n';
import FunctionalStar from './FunctionalStar';
import {
getDailyStarIndex,
getLuanXiIndex,
Expand All @@ -27,43 +28,55 @@ export const getAdjectiveStar = (solarDateStr: string, timeIndex: number, fixLea
const timelyIndex = getTimelyStarIndex(timeIndex);
const { hongluanIndex, tianxiIndex } = getLuanXiIndex(yearly[1]);

stars[hongluanIndex].push({ name: t('hongluan'), type: 'flower', scope: 'origin' });
stars[tianxiIndex].push({ name: t('tianxi'), type: 'flower', scope: 'origin' });
stars[monthlyIndex.tianyaoIndex].push({ name: t('tianyao'), type: 'flower', scope: 'origin' });
stars[yearlyIndex.xianchiIndex].push({ name: t('xianchi'), type: 'flower', scope: 'origin' });
stars[monthlyIndex.yuejieIndex].push({ name: t('jieshen'), type: 'helper', scope: 'origin' });
stars[dailyIndex.santaiIndex].push({ name: t('santai'), type: 'adjective', scope: 'origin' });
stars[dailyIndex.bazuoIndex].push({ name: t('bazuo'), type: 'adjective', scope: 'origin' });
stars[dailyIndex.enguangIndex].push({ name: t('engguang'), type: 'adjective', scope: 'origin' });
stars[dailyIndex.tianguiIndex].push({ name: t('tiangui'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.longchiIndex].push({ name: t('longchi'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.fenggeIndex].push({ name: t('fengge'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tiancaiIndex].push({ name: t('tiancai'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tianshouIndex].push({ name: t('tianshou'), type: 'adjective', scope: 'origin' });
stars[timelyIndex.taifuIndex].push({ name: t('taifu'), type: 'adjective', scope: 'origin' });
stars[timelyIndex.fenggaoIndex].push({ name: t('fenggao'), type: 'adjective', scope: 'origin' });
stars[monthlyIndex.tianwuIndex].push({ name: t('tianwu'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.huagaiIndex].push({ name: t('huagai'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tianguanIndex].push({ name: t('tianguan'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tianfuIndex].push({ name: t('tianfu'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tianchuIndex].push({ name: t('tianchu'), type: 'adjective', scope: 'origin' });
stars[monthlyIndex.tianyueIndex].push({ name: t('tianyue'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tiandeIndex].push({ name: t('tiande'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.yuedeIndex].push({ name: t('yuede'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tiankongIndex].push({ name: t('tiankong'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.xunkongIndex].push({ name: t('xunkong'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.jieluIndex].push({ name: t('jielu'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.kongwangIndex].push({ name: t('kongwang'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.guchenIndex].push({ name: t('guchen'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.guasuIndex].push({ name: t('guasu'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.feilianIndex].push({ name: t('feilian'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.posuiIndex].push({ name: t('posui'), type: 'adjective', scope: 'origin' });
stars[monthlyIndex.tianxingIndex].push({ name: t('tianxing'), type: 'adjective', scope: 'origin' });
stars[monthlyIndex.yinshaIndex].push({ name: t('yinsha'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tiankuIndex].push({ name: t('tianku'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tianxuIndex].push({ name: t('tianxu'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tianshiIndex].push({ name: t('tianshi'), type: 'adjective', scope: 'origin' });
stars[yearlyIndex.tianshangIndex].push({ name: t('tianshang'), type: 'adjective', scope: 'origin' });
stars[hongluanIndex].push(new FunctionalStar({ name: t('hongluan'), type: 'flower', scope: 'origin' }));
stars[tianxiIndex].push(new FunctionalStar({ name: t('tianxi'), type: 'flower', scope: 'origin' }));
stars[monthlyIndex.tianyaoIndex].push(new FunctionalStar({ name: t('tianyao'), type: 'flower', scope: 'origin' }));
stars[yearlyIndex.xianchiIndex].push(new FunctionalStar({ name: t('xianchi'), type: 'flower', scope: 'origin' }));
stars[monthlyIndex.yuejieIndex].push(new FunctionalStar({ name: t('jieshen'), type: 'helper', scope: 'origin' }));
stars[dailyIndex.santaiIndex].push(new FunctionalStar({ name: t('santai'), type: 'adjective', scope: 'origin' }));
stars[dailyIndex.bazuoIndex].push(new FunctionalStar({ name: t('bazuo'), type: 'adjective', scope: 'origin' }));
stars[dailyIndex.enguangIndex].push(new FunctionalStar({ name: t('engguang'), type: 'adjective', scope: 'origin' }));
stars[dailyIndex.tianguiIndex].push(new FunctionalStar({ name: t('tiangui'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.longchiIndex].push(new FunctionalStar({ name: t('longchi'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.fenggeIndex].push(new FunctionalStar({ name: t('fengge'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tiancaiIndex].push(new FunctionalStar({ name: t('tiancai'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tianshouIndex].push(
new FunctionalStar({ name: t('tianshou'), type: 'adjective', scope: 'origin' }),
);
stars[timelyIndex.taifuIndex].push(new FunctionalStar({ name: t('taifu'), type: 'adjective', scope: 'origin' }));
stars[timelyIndex.fenggaoIndex].push(new FunctionalStar({ name: t('fenggao'), type: 'adjective', scope: 'origin' }));
stars[monthlyIndex.tianwuIndex].push(new FunctionalStar({ name: t('tianwu'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.huagaiIndex].push(new FunctionalStar({ name: t('huagai'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tianguanIndex].push(
new FunctionalStar({ name: t('tianguan'), type: 'adjective', scope: 'origin' }),
);
stars[yearlyIndex.tianfuIndex].push(new FunctionalStar({ name: t('tianfu'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tianchuIndex].push(new FunctionalStar({ name: t('tianchu'), type: 'adjective', scope: 'origin' }));
stars[monthlyIndex.tianyueIndex].push(new FunctionalStar({ name: t('tianyue'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tiandeIndex].push(new FunctionalStar({ name: t('tiande'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.yuedeIndex].push(new FunctionalStar({ name: t('yuede'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tiankongIndex].push(
new FunctionalStar({ name: t('tiankong'), type: 'adjective', scope: 'origin' }),
);
stars[yearlyIndex.xunkongIndex].push(new FunctionalStar({ name: t('xunkong'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.jieluIndex].push(new FunctionalStar({ name: t('jielu'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.kongwangIndex].push(
new FunctionalStar({ name: t('kongwang'), type: 'adjective', scope: 'origin' }),
);
stars[yearlyIndex.guchenIndex].push(new FunctionalStar({ name: t('guchen'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.guasuIndex].push(new FunctionalStar({ name: t('guasu'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.feilianIndex].push(new FunctionalStar({ name: t('feilian'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.posuiIndex].push(new FunctionalStar({ name: t('posui'), type: 'adjective', scope: 'origin' }));
stars[monthlyIndex.tianxingIndex].push(
new FunctionalStar({ name: t('tianxing'), type: 'adjective', scope: 'origin' }),
);
stars[monthlyIndex.yinshaIndex].push(new FunctionalStar({ name: t('yinsha'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tiankuIndex].push(new FunctionalStar({ name: t('tianku'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tianxuIndex].push(new FunctionalStar({ name: t('tianxu'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tianshiIndex].push(new FunctionalStar({ name: t('tianshi'), type: 'adjective', scope: 'origin' }));
stars[yearlyIndex.tianshangIndex].push(
new FunctionalStar({ name: t('tianshang'), type: 'adjective', scope: 'origin' }),
);

return stars;
};
46 changes: 23 additions & 23 deletions src/star/horoscopeStar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { initStars } from '.';
import { Star } from '../data/types';
import { t, HeavenlyStemName, EarthlyBranchName } from '../i18n';
import FunctionalStar from './FunctionalStar';
import {
getChangQuIndexByHeavenlyStem,
getKuiYueIndex,
Expand All @@ -21,7 +21,7 @@ export const getHoroscopeStar = (
heavenlyStem: HeavenlyStemName,
earthlyBranch: EarthlyBranchName,
scope: 'decadal' | 'yearly',
): Star[][] => {
): FunctionalStar[][] => {
const { kuiIndex, yueIndex } = getKuiYueIndex(heavenlyStem);
const { changIndex, quIndex } = getChangQuIndexByHeavenlyStem(heavenlyStem);
const { luIndex, yangIndex, tuoIndex, maIndex } = getLuYangTuoMaIndex(heavenlyStem, earthlyBranch);
Expand All @@ -31,28 +31,28 @@ export const getHoroscopeStar = (
if (scope === 'yearly') {
const nianjieIndex = getNianjieIndex(earthlyBranch);

stars[nianjieIndex].push({ name: t('nianjie'), type: 'helper', scope: 'yearly' });
stars[kuiIndex].push({ name: t('liukui'), type: 'soft', scope });
stars[yueIndex].push({ name: t('liuyue'), type: 'soft', scope });
stars[changIndex].push({ name: t('liuchang'), type: 'soft', scope });
stars[quIndex].push({ name: t('liuqu'), type: 'soft', scope });
stars[luIndex].push({ name: t('liulu'), type: 'lucun', scope });
stars[yangIndex].push({ name: t('liuyang'), type: 'tough', scope });
stars[tuoIndex].push({ name: t('liutuo'), type: 'tough', scope });
stars[maIndex].push({ name: t('liuma'), type: 'tianma', scope });
stars[hongluanIndex].push({ name: t('liuluan'), type: 'flower', scope });
stars[tianxiIndex].push({ name: t('liuxi'), type: 'flower', scope });
stars[nianjieIndex].push(new FunctionalStar({ name: t('nianjie'), type: 'helper', scope: 'yearly' }));
stars[kuiIndex].push(new FunctionalStar({ name: t('liukui'), type: 'soft', scope }));
stars[yueIndex].push(new FunctionalStar({ name: t('liuyue'), type: 'soft', scope }));
stars[changIndex].push(new FunctionalStar({ name: t('liuchang'), type: 'soft', scope }));
stars[quIndex].push(new FunctionalStar({ name: t('liuqu'), type: 'soft', scope }));
stars[luIndex].push(new FunctionalStar({ name: t('liulu'), type: 'lucun', scope }));
stars[yangIndex].push(new FunctionalStar({ name: t('liuyang'), type: 'tough', scope }));
stars[tuoIndex].push(new FunctionalStar({ name: t('liutuo'), type: 'tough', scope }));
stars[maIndex].push(new FunctionalStar({ name: t('liuma'), type: 'tianma', scope }));
stars[hongluanIndex].push(new FunctionalStar({ name: t('liuluan'), type: 'flower', scope }));
stars[tianxiIndex].push(new FunctionalStar({ name: t('liuxi'), type: 'flower', scope }));
} else {
stars[kuiIndex].push({ name: t('yunkui'), type: 'soft', scope });
stars[yueIndex].push({ name: t('yunyue'), type: 'soft', scope });
stars[changIndex].push({ name: t('yunchang'), type: 'soft', scope });
stars[quIndex].push({ name: t('yunqu'), type: 'soft', scope });
stars[luIndex].push({ name: t('yunlu'), type: 'lucun', scope });
stars[yangIndex].push({ name: t('yunyang'), type: 'tough', scope });
stars[tuoIndex].push({ name: t('yuntuo'), type: 'tough', scope });
stars[maIndex].push({ name: t('yunma'), type: 'tianma', scope });
stars[hongluanIndex].push({ name: t('yunluan'), type: 'flower', scope });
stars[tianxiIndex].push({ name: t('yunxi'), type: 'flower', scope });
stars[kuiIndex].push(new FunctionalStar({ name: t('yunkui'), type: 'soft', scope }));
stars[yueIndex].push(new FunctionalStar({ name: t('yunyue'), type: 'soft', scope }));
stars[changIndex].push(new FunctionalStar({ name: t('yunchang'), type: 'soft', scope }));
stars[quIndex].push(new FunctionalStar({ name: t('yunqu'), type: 'soft', scope }));
stars[luIndex].push(new FunctionalStar({ name: t('yunlu'), type: 'lucun', scope }));
stars[yangIndex].push(new FunctionalStar({ name: t('yunyang'), type: 'tough', scope }));
stars[tuoIndex].push(new FunctionalStar({ name: t('yuntuo'), type: 'tough', scope }));
stars[maIndex].push(new FunctionalStar({ name: t('yunma'), type: 'tianma', scope }));
stars[hongluanIndex].push(new FunctionalStar({ name: t('yunluan'), type: 'flower', scope }));
stars[tianxiIndex].push(new FunctionalStar({ name: t('yunxi'), type: 'flower', scope }));
}

return stars;
Expand Down
4 changes: 2 additions & 2 deletions src/star/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Star } from '../data/types';
import FunctionalStar from './FunctionalStar';

export const initStars = (): Star[][] => [[], [], [], [], [], [], [], [], [], [], [], []];
export const initStars = (): FunctionalStar[][] => [[], [], [], [], [], [], [], [], [], [], [], []];

export * from './location';
export * from './majorStar';
Expand Down
Loading

0 comments on commit af266ab

Please sign in to comment.