`;
} else {
returnHtml = calendar;
const displayInput = (document.querySelector(`#${this.id} .display-input`));
@@ -460,14 +530,14 @@ export default class DateSelector {
}
if(html){
const dateSelector = html;
- if(this.showDate){
- if(!justCalendar){
- document.addEventListener('click', this.hideCalendar.bind(this,html));
- const di = html.querySelector('.display-input');
- if(di){
- di.addEventListener('click', this.toggleCalendar.bind(this, dateSelector));
- }
+ if(!justCalendar){
+ document.addEventListener('click', this.hideCalendar.bind(this,html));
+ const di = html.querySelector('.display-input');
+ if(di){
+ di.addEventListener('click', this.toggleCalendar.bind(this, dateSelector));
}
+ }
+ if(this.showDate){
const cal = html.querySelector('.sc-date-selector-calendar');
if(cal){
cal.addEventListener('click', this.calendarClick.bind(this));
@@ -494,13 +564,13 @@ export default class DateSelector {
if(cb){
cb.addEventListener('click', this.removeTimeClick.bind(this));
}
- html.querySelectorAll('.time-container .time-selectors input').forEach(el => {
+ html.querySelectorAll('.time-container input').forEach(el => {
el.addEventListener('click', this.timeClick.bind(this));
});
- html.querySelectorAll('.time-container .time-selectors .time-dropdown .time-option').forEach(el => {
+ html.querySelectorAll('.time-container .time-dropdown .time-option').forEach(el => {
el.addEventListener('click', this.timeDropdownClick.bind(this));
});
- html.querySelectorAll('.time-container .time-selectors input').forEach(el => {
+ html.querySelectorAll('.time-container input').forEach(el => {
el.addEventListener('change', this.timeUpdate.bind(this));
});
}
@@ -576,7 +646,7 @@ export default class DateSelector {
const yearNumber = parseInt(my[1]);
if(!isNaN(yearNumber) && !isNaN(monthNumber) && !isNaN(dayNumber)){
let hideCalendar = true;
- if(this.range){
+ if(this.dateRange){
if(!this.secondDaySelect){
this.selectedDate.startDate.year = yearNumber;
this.selectedDate.startDate.month = monthNumber;
@@ -861,6 +931,9 @@ export default class DateSelector {
this.selectedDate.endDate.minute = minute;
}
this.update();
+ if(this.showTime && !this.showDate && this.onDateSelect){
+ this.onDateSelect(this.selectedDate);
+ }
}
}
}
diff --git a/src/classes/game-settings.test.ts b/src/classes/game-settings.test.ts
index cef9ccdd..2877f821 100644
--- a/src/classes/game-settings.test.ts
+++ b/src/classes/game-settings.test.ts
@@ -86,12 +86,7 @@ describe('Game Settings Class Tests', () => {
SimpleCalendar.instance = new SimpleCalendar();
GameSettings.RegisterSettings();
expect((game).settings.register).toHaveBeenCalled();
- expect((game).settings.register).toHaveBeenCalledTimes(14);
- });
-
- test('Get Import Ran', () => {
- expect(GameSettings.GetImportRan()).toBe(false);
- expect((game).settings.get).toHaveBeenCalled();
+ expect((game).settings.register).toHaveBeenCalledTimes(13);
});
test('Get Default Note Visibility', () => {
@@ -137,7 +132,7 @@ describe('Game Settings Class Tests', () => {
});
test('Load Season Data', () => {
- expect(GameSettings.LoadSeasonData()).toStrictEqual([{name:'', startingMonth: 1, startingDay: 1, color: '#ffffff'}]);
+ expect(GameSettings.LoadSeasonData()).toStrictEqual([{name:'', startingMonth: 1, startingDay: 1, color: '#ffffff', sunriseTime: 0, sunsetTime: 0}]);
expect((game).settings.get).toHaveBeenCalled();
((game).settings.get).mockReturnValueOnce(false);
expect(GameSettings.LoadSeasonData()).toStrictEqual([]);
@@ -164,7 +159,7 @@ describe('Game Settings Class Tests', () => {
});
test('Load Time Data', () => {
- expect(GameSettings.LoadTimeData()).toStrictEqual({hoursInDay:0, minutesInHour: 1, secondsInMinute: 2, gameTimeRatio: 3, unifyGameAndClockPause: false, updateFrequency: 1});
+ expect(GameSettings.LoadTimeData()).toStrictEqual({hoursInDay:0, minutesInHour: 1, secondsInMinute: 2, gameTimeRatio: 3, unifyGameAndClockPause: false, updateFrequency: 1, secondsInCombatRound: 6});
expect((game).settings.get).toHaveBeenCalled();
});
@@ -188,16 +183,6 @@ describe('Game Settings Class Tests', () => {
expect(GameSettings.LoadNoteCategories()).toStrictEqual([{name: "Holiday", color: "#148e94", textColor: "#FFFFFF"}]);
});
- test('Set Import Ran', async () => {
- // @ts-ignore
- game.user.isGM = false;
- await expect(GameSettings.SetImportRan(true)).resolves.toBe(false);
- // @ts-ignore
- game.user.isGM = true;
- await expect(GameSettings.SetImportRan(true)).resolves.toBe(true);
- expect((game).settings.set).toHaveBeenCalled();
- });
-
test('Save General Settings', async () => {
// @ts-ignore
game.user.isGM = false;
diff --git a/src/classes/game-settings.ts b/src/classes/game-settings.ts
index 147c91f8..7a167095 100644
--- a/src/classes/game-settings.ts
+++ b/src/classes/game-settings.ts
@@ -149,13 +149,6 @@ export class GameSettings {
default: {},
onChange: SimpleCalendar.instance.settingUpdate.bind(SimpleCalendar.instance, true, 'time')
});
- (game).settings.register(ModuleName, SettingNames.ImportRan, {
- name: "Import",
- scope: "world",
- config: false,
- type: Boolean,
- default: false
- });
(game).settings.register(ModuleName, SettingNames.SeasonConfiguration, {
name: "Season Configuration",
scope: "world",
@@ -192,13 +185,6 @@ export class GameSettings {
}
- /**
- * Gets if the import question has been run for modules
- */
- static GetImportRan(){
- return (game).settings.get(ModuleName, SettingNames.ImportRan);
- }
-
/**
* Gets the default note visibility setting
* @return {boolean}
@@ -347,18 +333,6 @@ export class GameSettings {
return returnData;
}
- /**
- * Sets the import ran setting
- * @param {boolean} ran If the import was ran/asked about
- */
- static async SetImportRan(ran: boolean){
- if(GameSettings.IsGm()){
- await (game).settings.set(ModuleName, SettingNames.ImportRan, ran);
- return true;
- }
- return false;
- }
-
/**
* Saves the general settings to the world settings
* @param {GeneralSettings} settings The settings to save
@@ -502,7 +476,7 @@ export class GameSettings {
if(GameSettings.IsGm()){
Logger.debug('Saving season configuration.');
const currentConfig = JSON.stringify(GameSettings.LoadSeasonData());
- const newConfig: SeasonConfiguration[] = seasons.map(s => {return {name: s.name, startingMonth: s.startingMonth, startingDay: s.startingDay, color: s.color}});
+ const newConfig: SeasonConfiguration[] = seasons.map(s => {return {name: s.name, startingMonth: s.startingMonth, startingDay: s.startingDay, color: s.color, sunriseTime: s.sunriseTime, sunsetTime: s.sunsetTime}});
if(currentConfig !== JSON.stringify(newConfig)){
return (game).settings.set(ModuleName, SettingNames.SeasonConfiguration, newConfig).then(() => {return true;});
} else {
@@ -571,6 +545,7 @@ export class GameSettings {
hoursInDay: time.hoursInDay,
minutesInHour: time.minutesInHour,
secondsInMinute: time.secondsInMinute,
+ secondsInCombatRound: time.secondsInCombatRound,
gameTimeRatio: time.gameTimeRatio,
unifyGameAndClockPause: time.unifyGameAndClockPause,
updateFrequency: time.updateFrequency
diff --git a/src/classes/predefined-calendar.ts b/src/classes/predefined-calendar.ts
index 31fd25d8..0a4aceb0 100644
--- a/src/classes/predefined-calendar.ts
+++ b/src/classes/predefined-calendar.ts
@@ -61,6 +61,14 @@ export default class PredefinedCalendar{
year.seasons[1].color = "#f3fff3";
year.seasons[2].color = "#fff7f2";
year.seasons[3].color = "#f2f8ff";
+ year.seasons[0].sunriseTime = 21600;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 21600;
+ year.seasons[3].sunriseTime = 21600;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 64800;
+ year.seasons[2].sunsetTime = 64800;
+ year.seasons[3].sunsetTime = 64800;
year.moons = [
new Moon('Moon', 29.53059)
];
@@ -128,6 +136,12 @@ export default class PredefinedCalendar{
year.seasons[2].color = '#fff2da';
year.seasons[0].color = '#dececc';
year.seasons[1].color = '#fff1e7';
+ year.seasons[0].sunriseTime = 21600;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 21600;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 64800;
+ year.seasons[2].sunsetTime = 64800;
year.time.hoursInDay = 24;
year.time.minutesInHour = 60;
year.time.secondsInMinute = 60;
@@ -347,6 +361,14 @@ export default class PredefinedCalendar{
year.seasons[1].color = "#f3fff3";
year.seasons[2].color = "#fff7f2";
year.seasons[3].color = "#f2f8ff";
+ year.seasons[0].sunriseTime = 27000;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 27000;
+ year.seasons[3].sunriseTime = 32400;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 75600;
+ year.seasons[2].sunsetTime = 64800;
+ year.seasons[3].sunsetTime = 54000;
year.moons = [
new Moon('Catha', 33),
new Moon('Ruidus', 328)
@@ -429,6 +451,14 @@ export default class PredefinedCalendar{
year.seasons[1].color = "#ff9393";
year.seasons[2].color = "#ffdf99";
year.seasons[3].color = "#a8a8ff";
+ year.seasons[0].sunriseTime = 21600;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 21600;
+ year.seasons[3].sunriseTime = 21600;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 64800;
+ year.seasons[2].sunsetTime = 64800;
+ year.seasons[3].sunsetTime = 64800;
year.time.hoursInDay = 24;
year.time.minutesInHour = 60;
@@ -510,6 +540,14 @@ export default class PredefinedCalendar{
year.seasons[1].color = "#f3fff3";
year.seasons[2].color = "#fff7f2";
year.seasons[3].color = "#f2f8ff";
+ year.seasons[0].sunriseTime = 21600;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 21600;
+ year.seasons[3].sunriseTime = 21600;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 64800;
+ year.seasons[2].sunsetTime = 64800;
+ year.seasons[3].sunsetTime = 64800;
year.moons = [
new Moon('Somal', 29.5)
];
@@ -582,6 +620,14 @@ export default class PredefinedCalendar{
year.seasons[1].color = "#f3fff3";
year.seasons[2].color = "#fff7f2";
year.seasons[3].color = "#f2f8ff";
+ year.seasons[0].sunriseTime = 21600;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 21600;
+ year.seasons[3].sunriseTime = 21600;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 64800;
+ year.seasons[2].sunsetTime = 64800;
+ year.seasons[3].sunsetTime = 64800;
year.moons = [
new Moon('Somal', 29.5)
];
@@ -656,6 +702,16 @@ export default class PredefinedCalendar{
year.seasons[2].color = "#f3fff3";
year.seasons[3].color = "#fff7f2";
year.seasons[4].color = "#f2f8ff";
+ year.seasons[0].sunriseTime = 24300;
+ year.seasons[1].sunriseTime = 18840;
+ year.seasons[2].sunriseTime = 16500;
+ year.seasons[3].sunriseTime = 20400;
+ year.seasons[4].sunriseTime = 25740;
+ year.seasons[0].sunsetTime = 48360;
+ year.seasons[1].sunsetTime = 66540;
+ year.seasons[2].sunsetTime = 69540;
+ year.seasons[3].sunsetTime = 64140;
+ year.seasons[4].sunsetTime = 59160;
year.time.hoursInDay = 24;
year.time.minutesInHour = 60;
year.time.secondsInMinute = 60;
@@ -759,6 +815,14 @@ export default class PredefinedCalendar{
year.seasons[1].color = "#f3fff3";
year.seasons[2].color = "#fff7f2";
year.seasons[3].color = "#f2f8ff";
+ year.seasons[0].sunriseTime = 21600;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 21600;
+ year.seasons[3].sunriseTime = 21600;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 64800;
+ year.seasons[2].sunsetTime = 64800;
+ year.seasons[3].sunsetTime = 64800;
year.time.hoursInDay = 24;
year.time.minutesInHour = 60;
year.time.secondsInMinute = 60;
@@ -880,6 +944,14 @@ export default class PredefinedCalendar{
year.seasons[1].color = "#f3fff3";
year.seasons[2].color = "#fff7f2";
year.seasons[3].color = "#f2f8ff";
+ year.seasons[0].sunriseTime = 21600;
+ year.seasons[1].sunriseTime = 21600;
+ year.seasons[2].sunriseTime = 21600;
+ year.seasons[3].sunriseTime = 21600;
+ year.seasons[0].sunsetTime = 64800;
+ year.seasons[1].sunsetTime = 64800;
+ year.seasons[2].sunsetTime = 64800;
+ year.seasons[3].sunsetTime = 64800;
year.time.hoursInDay = 24;
year.time.minutesInHour = 60;
year.time.secondsInMinute = 60;
diff --git a/src/classes/season.test.ts b/src/classes/season.test.ts
index 9fe58bea..46806534 100644
--- a/src/classes/season.test.ts
+++ b/src/classes/season.test.ts
@@ -19,14 +19,20 @@ describe('Season Tests', () => {
beforeEach(() => {
s = new Season('Spring', 1, 1);
+
+ // @ts-ignore
+ SimpleCalendar.instance = undefined;
});
test('Properties', () => {
- expect(Object.keys(s).length).toBe(4); //Make sure no new properties have been added
+ expect(Object.keys(s).length).toBe(7); //Make sure no new properties have been added
+ expect(s.id).toBeDefined();
expect(s.name).toBe('Spring');
expect(s.startingMonth).toBe(1);
expect(s.startingDay).toBe(1);
expect(s.color).toBe('#ffffff');
+ expect(s.sunriseTime).toBe(0);
+ expect(s.sunsetTime).toBe(0);
});
test('Clone', () => {
@@ -36,20 +42,55 @@ describe('Season Tests', () => {
test('To Template', () => {
const y = new Year(0);
let c = s.toTemplate(y);
- expect(Object.keys(c).length).toBe(5); //Make sure no new properties have been added
+ expect(Object.keys(c).length).toBe(6); //Make sure no new properties have been added
expect(c.name).toBe('Spring');
expect(c.startingMonth).toBe(1);
expect(c.startingDay).toBe(1);
expect(c.color).toBe('#ffffff');
- expect(c.dayList).toStrictEqual([]);
+ expect(c.startDateSelectorId).toBeDefined();
+ expect(c.sunriseSelectorId).toBeDefined();
SimpleCalendar.instance = new SimpleCalendar();
-
+ SimpleCalendar.instance.currentYear = new Year(0);
c = s.toTemplate(y);
- expect(c.dayList.length).toStrictEqual(0);
- y.months.push(new Month("Month 1", 1, 0, 10));
+
+ s.sunriseTime = 3660;
+ s.sunsetTime = 3660;
c = s.toTemplate(y);
- expect(c.dayList.length).toStrictEqual(10);
+ });
+
+ test('Start Date Change', () => {
+ s.startDateChange({
+ startDate: { year: 0, month: 2, day: 4, minute: 0, hour: 0, allDay: true },
+ endDate: { year: 0, month: 2, day: 4, minute: 0, hour: 0, allDay: true },
+ visibleDate: { year: 0, month: 2, day: 4, minute: 0, hour: 0, allDay: true }
+ });
+ expect(s.startingMonth).toBe(2);
+ expect(s.startingDay).toBe(4);
+ });
+
+ test('Sunrise Sunset Change', () => {
+ s.sunriseSunsetChange({
+ startDate: { year: 0, month: 1, day: 1, minute: 30, hour: 2, allDay: false },
+ endDate: { year: 0, month: 1, day: 1, minute: 0, hour: 4, allDay: false },
+ visibleDate: { year: 0, month: 1, day: 1, minute: 0, hour: 0, allDay: false }
+ });
+ expect(s.sunriseTime).toBe(0);
+ expect(s.sunsetTime).toBe(0);
+
+ SimpleCalendar.instance = new SimpleCalendar();
+ SimpleCalendar.instance.currentYear = new Year(0);
+ s.sunriseSunsetChange({
+ startDate: { year: 0, month: 1, day: 1, minute: 30, hour: 2, allDay: false },
+ endDate: { year: 0, month: 1, day: 1, minute: 0, hour: 4, allDay: false },
+ visibleDate: { year: 0, month: 1, day: 1, minute: 0, hour: 0, allDay: false }
+ });
+ expect(s.sunriseTime).toBe(9000);
+ expect(s.sunsetTime).toBe(14400);
+ });
+
+ test('Activate Date Selectors', () => {
+ s.activateDateSelectors();
});
});
diff --git a/src/classes/season.ts b/src/classes/season.ts
index d9ccc5a4..fc568826 100644
--- a/src/classes/season.ts
+++ b/src/classes/season.ts
@@ -1,10 +1,15 @@
-import {SeasonTemplate} from "../interfaces";
+import {SCDateSelector, SeasonTemplate} from "../interfaces";
import Year from "./year";
+import DateSelector from "./date-selector";
+import Utilities from "./utilities";
+import SimpleCalendar from "./simple-calendar";
/**
* All content around a season
*/
export default class Season {
+
+ id: string;
/**
* The name of the season
* @type{string}
@@ -25,10 +30,16 @@ export default class Season {
* @type{number}
*/
startingDay: number = -1;
-
- //sunriseTime: number = 0;
-
- //sunsetTime: number = 0;
+ /**
+ * The time, in seconds, that the sun rises
+ * @type{number}
+ */
+ sunriseTime: number = 0;
+ /**
+ * The time, in seconds, that the sun sets
+ * @type{number}
+ */
+ sunsetTime: number = 0;
/**
* The Season Constructor
@@ -37,6 +48,7 @@ export default class Season {
* @param {number} startingDay The day of the starting month this season starts on
*/
constructor(name: string, startingMonth: number, startingDay: number) {
+ this.id = Utilities.generateUniqueId();
this.name = name;
this.startingMonth = startingMonth;
this.startingDay = startingDay;
@@ -48,9 +60,10 @@ export default class Season {
*/
clone(): Season {
const t = new Season(this.name, this.startingMonth, this.startingDay);
+ t.id = this.id;
t.color = this.color;
- //t.sunriseTime = this.sunriseTime;
- //t.sunsetTime = this.sunsetTime;
+ t.sunriseTime = this.sunriseTime;
+ t.sunsetTime = this.sunsetTime;
return t;
}
@@ -59,18 +72,82 @@ export default class Season {
* @param {Year} year The year to look in for the months and days list
*/
toTemplate(year: Year){
+ const startDateSelectorId = `sc_season_start_date_${this.id}`;
+ const sunriseSelectorId = `sc_season_sunrise_time_${this.id}`;
const data: SeasonTemplate = {
name: this.name,
startingMonth: this.startingMonth,
startingDay: this.startingDay,
color: this.color,
- dayList: []
+ startDateSelectorId: startDateSelectorId,
+ sunriseSelectorId: sunriseSelectorId
};
- const month = year.months.find(m => m.numericRepresentation === data.startingMonth);
- if(month){
- data.dayList = month.days.map(d => d.toTemplate());
+ DateSelector.GetSelector(startDateSelectorId, {
+ showDate: true,
+ showYear: false,
+ showTime: false,
+ dateRangeSelect: false,
+ inputMatchCalendarWidth: false,
+ startDate:{year: 0, month: this.startingMonth, day: this.startingDay, hour: 0, minute: 0, seconds: 0},
+ allDay: true,
+ onDateSelect: this.startDateChange.bind(this)
+ });
+
+ let sunriseHour = 0, sunriseMinute = 0, sunsetHour = 0, sunsetMinute = 0;
+ if(SimpleCalendar.instance && SimpleCalendar.instance.currentYear){
+ sunriseMinute = Math.floor(this.sunriseTime / SimpleCalendar.instance.currentYear.time.secondsInMinute);
+ sunsetMinute = Math.floor(this.sunsetTime / SimpleCalendar.instance.currentYear.time.secondsInMinute);
+ if(sunriseMinute >= SimpleCalendar.instance.currentYear.time.minutesInHour){
+ sunriseHour = Math.floor(sunriseMinute / SimpleCalendar.instance.currentYear.time.minutesInHour);
+ sunriseMinute = sunriseMinute - (sunriseHour * SimpleCalendar.instance.currentYear.time.minutesInHour);
+ }
+ if(sunsetMinute >= SimpleCalendar.instance.currentYear.time.minutesInHour){
+ sunsetHour = Math.floor(sunsetMinute / SimpleCalendar.instance.currentYear.time.minutesInHour);
+ sunsetMinute = sunsetMinute - (sunsetHour * SimpleCalendar.instance.currentYear.time.minutesInHour);
+ }
}
+ DateSelector.GetSelector(sunriseSelectorId, {
+ showDate: false,
+ showTime: true,
+ dateRangeSelect: false,
+ timeRangeSelect: true,
+ showTimeLabel: false,
+ timeDelimiter: '/',
+ inputMatchCalendarWidth: false,
+ startDate:{year: 0, month: 1, day: 1, hour: sunriseHour, minute: sunriseMinute, seconds: 0},
+ endDate:{year: 0, month: 1, day: 1, hour: sunsetHour, minute: sunsetMinute, seconds: 0},
+ allDay: false,
+ onDateSelect: this.sunriseSunsetChange.bind(this)
+ });
return data;
}
+
+ /**
+ * Handles the start date selector changes
+ * @param {SCDateSelector.SelectedDate} selectedDate The date that was selected from the date selector
+ */
+ startDateChange(selectedDate: SCDateSelector.SelectedDate){
+ this.startingMonth = selectedDate.startDate.month;
+ this.startingDay = selectedDate.startDate.day;
+ }
+
+ /**
+ * Handles the Sunrise and Sunset date selector changes
+ * @param {SCDateSelector.SelectedDate} selectedDate The date/time that was selected from the date selector
+ */
+ sunriseSunsetChange(selectedDate: SCDateSelector.SelectedDate){
+ if(SimpleCalendar.instance && SimpleCalendar.instance.currentYear){
+ this.sunriseTime = (selectedDate.startDate.hour * SimpleCalendar.instance.currentYear.time.minutesInHour * SimpleCalendar.instance.currentYear.time.secondsInMinute) + (selectedDate.startDate.minute * SimpleCalendar.instance.currentYear.time.secondsInMinute);
+ this.sunsetTime = (selectedDate.endDate.hour * SimpleCalendar.instance.currentYear.time.minutesInHour * SimpleCalendar.instance.currentYear.time.secondsInMinute) + (selectedDate.endDate.minute * SimpleCalendar.instance.currentYear.time.secondsInMinute);
+ }
+ }
+
+ /**
+ * Activates the listeners for the date selectors used by the season.
+ */
+ activateDateSelectors(){
+ DateSelector.GetSelector(`sc_season_start_date_${this.id}`, {showDate: true, showTime: false}).activateListeners();
+ DateSelector.GetSelector( `sc_season_sunrise_time_${this.id}`, {showDate: false, showTime: true}).activateListeners();
+ }
}
diff --git a/src/classes/simple-calendar-configuration.test.ts b/src/classes/simple-calendar-configuration.test.ts
index c44e1e6c..00eae445 100644
--- a/src/classes/simple-calendar-configuration.test.ts
+++ b/src/classes/simple-calendar-configuration.test.ts
@@ -794,22 +794,6 @@ describe('Simple Calendar Configuration Tests', () => {
SimpleCalendarConfiguration.instance.inputChange(event);
expect((SimpleCalendarConfiguration.instance.object).seasons[0].name).toBe('Wint');
- (event.currentTarget).setAttribute('class', 'season-month');
- (event.currentTarget).value = '2';
- SimpleCalendarConfiguration.instance.inputChange(event);
- expect((SimpleCalendarConfiguration.instance.object).seasons[0].startingMonth).toBe(2);
- (event.currentTarget).value = 'qwe';
- SimpleCalendarConfiguration.instance.inputChange(event);
- expect((SimpleCalendarConfiguration.instance.object).seasons[0].startingMonth).toBe(2);
-
- (event.currentTarget).setAttribute('class', 'season-day');
- (event.currentTarget).value = '2';
- SimpleCalendarConfiguration.instance.inputChange(event);
- expect((SimpleCalendarConfiguration.instance.object).seasons[0].startingDay).toBe(2);
- (event.currentTarget).value = 'qwe';
- SimpleCalendarConfiguration.instance.inputChange(event);
- expect((SimpleCalendarConfiguration.instance.object).seasons[0].startingDay).toBe(2);
-
(event.currentTarget).setAttribute('class', 'season-color');
(event.currentTarget).value = '#fffeee';
SimpleCalendarConfiguration.instance.inputChange(event);
@@ -1108,6 +1092,16 @@ describe('Simple Calendar Configuration Tests', () => {
SimpleCalendarConfiguration.instance.inputChange(event);
expect((SimpleCalendarConfiguration.instance.object).time.secondsInMinute).toBe(10);
+ //Invalid seconds in combat round
+ (event.currentTarget).id = "scSecondsInCombatRound";
+ (event.currentTarget).value = 'asd';
+ SimpleCalendarConfiguration.instance.inputChange(event);
+ expect((SimpleCalendarConfiguration.instance.object).time.secondsInCombatRound).toBe(6);
+ //Valid seconds in combat round
+ (event.currentTarget).value = '10';
+ SimpleCalendarConfiguration.instance.inputChange(event);
+ expect((SimpleCalendarConfiguration.instance.object).time.secondsInCombatRound).toBe(10);
+
//Invalid game time ratio
(event.currentTarget).id = "scGameTimeRatio";
(event.currentTarget).value = 'asd';
@@ -1337,27 +1331,21 @@ describe('Simple Calendar Configuration Tests', () => {
await SimpleCalendarConfiguration.instance.overwriteConfirmationYes('tp-import', 'b');
expect(renderSpy).toHaveBeenCalledTimes(1);
- expect((game).settings.set).toHaveBeenCalledTimes(1);
await SimpleCalendarConfiguration.instance.overwriteConfirmationYes('tp-import', 'about-time');
expect(renderSpy).toHaveBeenCalledTimes(2);
- expect((game).settings.set).toHaveBeenCalledTimes(2);
await SimpleCalendarConfiguration.instance.overwriteConfirmationYes('tp-import', 'calendar-weather');
expect(renderSpy).toHaveBeenCalledTimes(3);
- expect((game).settings.set).toHaveBeenCalledTimes(3);
await SimpleCalendarConfiguration.instance.overwriteConfirmationYes('tp-export', 'b');
expect(renderSpy).toHaveBeenCalledTimes(3);
- expect((game).settings.set).toHaveBeenCalledTimes(4);
await SimpleCalendarConfiguration.instance.overwriteConfirmationYes('tp-export', 'about-time');
expect(renderSpy).toHaveBeenCalledTimes(3);
- expect((game).settings.set).toHaveBeenCalledTimes(5);
await SimpleCalendarConfiguration.instance.overwriteConfirmationYes('tp-export', 'calendar-weather');
expect(renderSpy).toHaveBeenCalledTimes(3);
- expect((game).settings.set).toHaveBeenCalledTimes(6);
((game).settings.set).mockClear();
});
diff --git a/src/classes/simple-calendar-configuration.ts b/src/classes/simple-calendar-configuration.ts
index b8a8942b..c54ad314 100644
--- a/src/classes/simple-calendar-configuration.ts
+++ b/src/classes/simple-calendar-configuration.ts
@@ -238,6 +238,7 @@ export class SimpleCalendarConfiguration extends FormApplication {
*/
public activateListeners(html: JQuery) {
super.activateListeners(html);
+ (this.object).seasons.forEach(s => s.activateDateSelectors());
if(html.hasOwnProperty("length")) {
//Month advanced click
(html).find(".month-show-advanced").on('click', this.inputChange.bind(this));
@@ -602,6 +603,11 @@ export class SimpleCalendarConfiguration extends FormApplication {
if(!isNaN(min)){
(this.object).time.secondsInMinute = min;
}
+ } else if(id === 'scSecondsInCombatRound'){
+ const s = parseInt(value);
+ if(!isNaN(s)){
+ (this.object).time.secondsInCombatRound = s;
+ }
} else if(id === 'scGameTimeRatio'){
const min = parseFloat(value);
if(!isNaN(min)){
@@ -630,17 +636,6 @@ export class SimpleCalendarConfiguration extends FormApplication {
//Season Setting Inputs
else if(cssClass === 'season-name' && (this.object).seasons.length > index){
(this.object).seasons[index].name = value;
- } else if(cssClass === 'season-month' && (this.object).seasons.length > index){
- const month = parseInt(value);
- if(!isNaN(month)){
- (this.object).seasons[index].startingMonth = month;
- (this.object).seasons[index].startingDay = 1;
- }
- } else if(cssClass === 'season-day' && (this.object).seasons.length > index){
- const day = parseInt(value);
- if(!isNaN(day)){
- (this.object).seasons[index].startingDay = day;
- }
} else if(cssClass === 'season-color' && (this.object).seasons.length > index){
(this.object).seasons[index].color = value;
}
@@ -850,14 +845,12 @@ export class SimpleCalendarConfiguration extends FormApplication {
await Importer.importCalendarWeather(this.object);
this.updateApp();
}
- await GameSettings.SetImportRan(true);
} else if(type === 'tp-export'){
if(type2 === 'about-time'){
await Importer.exportToAboutTime(this.object);
} else if(type2 === 'calendar-weather'){
await Importer.exportCalendarWeather(this.object);
}
- await GameSettings.SetImportRan(true);
}
}
@@ -914,7 +907,7 @@ export class SimpleCalendarConfiguration extends FormApplication {
}
this.closeApp();
- } catch (error){
+ } catch (error: any){
Logger.error(error);
}
}
diff --git a/src/classes/simple-calendar-notes.ts b/src/classes/simple-calendar-notes.ts
index 34476b90..123a62ab 100644
--- a/src/classes/simple-calendar-notes.ts
+++ b/src/classes/simple-calendar-notes.ts
@@ -56,11 +56,13 @@ export class SimpleCalendarNotes extends FormApplication {
this.dateSelector = DateSelector.GetSelector(this.dateSelectorId, {
onDateSelect: this.dateSelectorClick.bind(this),
placeHolderText: '',
- rangeSelect: true,
+ dateRangeSelect: true,
showDate: true,
- showTime: true
+ showTime: true,
+ startDate: {year: data.year, month: data.month, day: data.day, hour: data.hour, minute: data.minute, seconds: 0},
+ endDate: data.endDate,
+ allDay: data.allDay
});
- this.dateSelector.updateSelectedDate(data);
}
/**
diff --git a/src/classes/simple-calendar.test.ts b/src/classes/simple-calendar.test.ts
index 3996a9f1..15345d49 100644
--- a/src/classes/simple-calendar.test.ts
+++ b/src/classes/simple-calendar.test.ts
@@ -16,10 +16,18 @@ import SimpleCalendar from "./simple-calendar";
import Year from "./year";
import Month from "./month";
import {Note} from "./note";
-import {GameWorldTimeIntegrations, NoteRepeat, SettingNames, SocketTypes, TimeKeeperStatus} from "../constants";
+import {
+ GameWorldTimeIntegrations,
+ NoteRepeat,
+ PredefinedCalendars,
+ SettingNames,
+ SocketTypes,
+ TimeKeeperStatus
+} from "../constants";
import {SimpleCalendarSocket} from "../interfaces";
import {SimpleCalendarConfiguration} from "./simple-calendar-configuration";
import {Weekday} from "./weekday";
+import PredefinedCalendar from "./predefined-calendar";
import Mock = jest.Mock;
import SpyInstance = jest.SpyInstance;
@@ -83,7 +91,7 @@ describe('Simple Calendar Class Tests', () => {
expect(SimpleCalendar.instance.currentYear).toBeNull();
await SimpleCalendar.instance.init();
expect(Handlebars.registerHelper).toHaveBeenCalledTimes(3);
- expect((game).settings.register).toHaveBeenCalledTimes(14);
+ expect((game).settings.register).toHaveBeenCalledTimes(13);
expect((game).settings.get).toHaveBeenCalledTimes(12);
expect(SimpleCalendar.instance.currentYear?.numericRepresentation).toBe(0);
expect(SimpleCalendar.instance.currentYear?.months.length).toBe(1);
@@ -813,6 +821,11 @@ describe('Simple Calendar Class Tests', () => {
SimpleCalendar.instance.compactTimeControlClick(e);
expect(y.time.seconds).toBe(3661);
+ (e.currentTarget).setAttribute('data-type', 'midnight');
+ (e.currentTarget).setAttribute('data-amount', '');
+ SimpleCalendar.instance.compactTimeControlClick(e);
+ expect(y.time.seconds).toBe(0);
+
//@ts-ignore
game.user.isGM = false;
});
@@ -899,8 +912,14 @@ describe('Simple Calendar Class Tests', () => {
SimpleCalendar.instance.gmControlClick(event);
expect((game).settings.get).toHaveBeenCalledTimes(12);
+
+ (event.currentTarget).setAttribute('data-type', 'dawn');
+ SimpleCalendar.instance.gmControlClick(event);
+ expect(y.time.seconds).toBe(0);
+
// @ts-ignore
game.user.isGM = false;
+ (event.currentTarget).setAttribute('data-type', 'time');
SimpleCalendar.instance.gmControlClick(event);
expect(ui.notifications?.warn).toHaveBeenCalled();
@@ -937,6 +956,50 @@ describe('Simple Calendar Class Tests', () => {
game.users.find = orig;
});
+ test('Time of Day Control Click', () => {
+ SimpleCalendar.instance.timeOfDayControlClick('asd');
+ expect(y.time.seconds).toBe(0);
+
+ PredefinedCalendar.setToPredefined(y, PredefinedCalendars.Gregorian);
+ SimpleCalendar.instance.currentYear = y;
+ SimpleCalendar.instance.timeOfDayControlClick('asd');
+ expect(y.time.seconds).toBe(0);
+
+ SimpleCalendar.instance.timeOfDayControlClick('dawn');
+ expect(y.time.seconds).toBe(21600);
+ y.time.seconds = 22000;
+ SimpleCalendar.instance.timeOfDayControlClick('dawn');
+ expect(y.time.seconds).toBe(21600);
+
+ SimpleCalendar.instance.timeOfDayControlClick('midday');
+ expect(y.time.seconds).toBe(43200);
+ y.time.seconds = 44000;
+ SimpleCalendar.instance.timeOfDayControlClick('midday');
+ expect(y.time.seconds).toBe(43200);
+
+ SimpleCalendar.instance.timeOfDayControlClick('dusk');
+ expect(y.time.seconds).toBe(64800);
+ y.time.seconds = 65000;
+ SimpleCalendar.instance.timeOfDayControlClick('dusk');
+ expect(y.time.seconds).toBe(64800);
+
+ SimpleCalendar.instance.timeOfDayControlClick('midnight');
+ expect(y.time.seconds).toBe(0);
+
+ y.resetMonths();
+ y.months[0].current = true;
+ SimpleCalendar.instance.timeOfDayControlClick('dawn');
+ expect(y.time.seconds).toBe(0);
+ SimpleCalendar.instance.timeOfDayControlClick('dusk');
+ expect(y.time.seconds).toBe(0);
+
+ y.resetMonths();
+ SimpleCalendar.instance.timeOfDayControlClick('dawn');
+ expect(y.time.seconds).toBe(0);
+ SimpleCalendar.instance.timeOfDayControlClick('dusk');
+ expect(y.time.seconds).toBe(0);
+ });
+
test('Date Control Apply', () => {
// @ts-ignore
game.user.isGM = true;
@@ -1389,6 +1452,15 @@ describe('Simple Calendar Class Tests', () => {
//@ts-ignore
SimpleCalendar.instance.loadSeasonConfiguration();
expect(y.seasons[0].color).toBe('#ff0000');
+ expect(y.seasons[0].sunriseTime).toBe(0);
+ expect(y.seasons[0].sunsetTime).toBe(0);
+
+ (game).settings.get = () => {return [{name:'', startingMonth: 1, startingDay: 1, color: 'custom', customColor: '#ff0000', sunriseTime: 3600, sunsetTime: 7200}];}
+
+ //@ts-ignore
+ SimpleCalendar.instance.loadSeasonConfiguration();
+ expect(y.seasons[0].sunriseTime).toBe(3600);
+ expect(y.seasons[0].sunsetTime).toBe(7200);
(game).settings.get = orig;
});
@@ -1477,6 +1549,9 @@ describe('Simple Calendar Class Tests', () => {
//@ts-ignore
SimpleCalendar.instance.combatUpdate({started: true, scene: {id:"123"}}, {}, {advanceTime: 2});
expect(y.combatChangeTriggered).toBe(true);
+ //@ts-ignore
+ SimpleCalendar.instance.combatUpdate({started: true, scene: {id:"123"}}, {}, {advanceTime: 0});
+ expect(y.combatChangeTriggered).toBe(true);
//@ts-ignore
game.scenes = null;
@@ -1548,80 +1623,15 @@ describe('Simple Calendar Class Tests', () => {
});
test('Time Keeping Check', async () => {
- ((game).settings.get).mockClear();
- await SimpleCalendar.instance.timeKeepingCheck();
- expect((game).settings.get).not.toHaveBeenCalled();
-
- SimpleCalendar.instance.currentYear = y;
await SimpleCalendar.instance.timeKeepingCheck();
- expect((game).settings.get).not.toHaveBeenCalled();
- //@ts-ignore
- game.user.isGM = true;
- ((game).settings.get).mockReturnValueOnce(true);
- y.generalSettings.gameWorldTimeIntegration = GameWorldTimeIntegrations.Self;
- await SimpleCalendar.instance.timeKeepingCheck();
- expect((game).settings.get).toHaveBeenCalledTimes(1);
-
- ((game).modules.get)
- .mockReturnValueOnce(null).mockReturnValueOnce(null)
- .mockReturnValueOnce(null).mockReturnValueOnce({active:true})
- .mockReturnValueOnce({active:true}).mockReturnValueOnce(null);
- await SimpleCalendar.instance.timeKeepingCheck();
- expect((game).settings.get).toHaveBeenCalledTimes(2);
-
- await SimpleCalendar.instance.timeKeepingCheck();
- expect((game).settings.get).toHaveBeenCalledTimes(3);
- //@ts-ignore
- expect(DialogRenderer).toHaveBeenCalledTimes(3);
- await SimpleCalendar.instance.timeKeepingCheck();
- expect((game).settings.get).toHaveBeenCalledTimes(4);
- //@ts-ignore
- expect(DialogRenderer).toHaveBeenCalledTimes(4);
- });
-
- test('Module Import Click', async () => {
- //@ts-ignore
- game.user.isGM = true;
- await SimpleCalendar.instance.moduleImportClick('asd');
- expect(console.error).toHaveBeenCalledTimes(1);
- SimpleCalendar.instance.currentYear = y;
-
- await SimpleCalendar.instance.moduleImportClick('asd');
- expect((game).settings.set).toHaveBeenCalledTimes(1);
- await SimpleCalendar.instance.moduleImportClick('about-time');
- expect((game).settings.set).toHaveBeenCalledTimes(2);
- expect(renderSpy).toHaveBeenCalledTimes(1);
- await SimpleCalendar.instance.moduleImportClick('calendar-weather');
- expect((game).settings.set).toHaveBeenCalledTimes(3);
- expect(renderSpy).toHaveBeenCalledTimes(2);
- });
-
- test('Module Export Click', async () => {
- //@ts-ignore
+ // @ts-ignore
game.user.isGM = true;
- await SimpleCalendar.instance.moduleExportClick('asd');
- expect(console.error).toHaveBeenCalledTimes(1);
SimpleCalendar.instance.currentYear = y;
+ await SimpleCalendar.instance.timeKeepingCheck();
- await SimpleCalendar.instance.moduleExportClick('asd');
- expect((game).settings.set).toHaveBeenCalledTimes(1);
- await SimpleCalendar.instance.moduleExportClick('about-time');
- expect((game).settings.set).toHaveBeenCalledTimes(2);
- await SimpleCalendar.instance.moduleExportClick('calendar-weather');
- expect((game).settings.set).toHaveBeenCalledTimes(3);
- });
-
- test('Module Dialog No Change', async () => {
- ((game).settings.set).mockClear();
- //@ts-ignore
+ // @ts-ignore
game.user.isGM = false;
- await SimpleCalendar.instance.moduleDialogNoChangeClick();
- expect((game).settings.set).not.toHaveBeenCalled();
- //@ts-ignore
- game.user.isGM = true;
- await SimpleCalendar.instance.moduleDialogNoChangeClick();
- expect((game).settings.set).toHaveBeenCalledTimes(1);
});
test('Note Drag', () => {
@@ -1653,20 +1663,22 @@ describe('Simple Calendar Class Tests', () => {
(e.target).setAttribute('data-index', 'asd');
SimpleCalendar.instance.noteDragEnd(e);
- expect((game).settings.set).toHaveBeenCalledTimes(1);
+ expect((game).settings.set).toHaveBeenCalledTimes(0);
(e.target).setAttribute('data-index', SimpleCalendar.instance.notes[0].id);
SimpleCalendar.instance.noteDragEnd(e);
- expect((game).settings.set).toHaveBeenCalledTimes(2);
+ expect((game).settings.set).toHaveBeenCalledTimes(0);
const orig = (game).settings.get;
(game).settings.get =(moduleName: string, settingName: string) => { return [{id: SimpleCalendar.instance.notes[0].id}];};
SimpleCalendar.instance.noteDragEnd(e);
- expect((game).settings.set).toHaveBeenCalledTimes(3);
+ expect((game).settings.set).toHaveBeenCalledTimes(0);
(game).settings.get = orig;
});
test('Check Note Reminders', () => {
+ // @ts-ignore
+ game.user.isGM = true;
SimpleCalendar.instance.checkNoteReminders();
expect(ChatMessage.create).not.toHaveBeenCalled();
@@ -1783,5 +1795,8 @@ describe('Simple Calendar Class Tests', () => {
y.time.seconds = 0;
SimpleCalendar.instance.checkNoteReminders();
expect(ChatMessage.create).toHaveBeenCalledTimes(11);
+
+ // @ts-ignore
+ game.user.isGM = false;
});
});
diff --git a/src/classes/simple-calendar.ts b/src/classes/simple-calendar.ts
index 13bde545..6ecd6a73 100644
--- a/src/classes/simple-calendar.ts
+++ b/src/classes/simple-calendar.ts
@@ -453,7 +453,7 @@ export default class SimpleCalendar extends Application{
}
if(timeControls){
const h = timeControls.outerHeight(true);
- height += h? h : 0;
+ height += h? h * 2 : 0;
}
if(noteListNote){
@@ -746,6 +746,11 @@ export default class SimpleCalendar extends Application{
//Sync the current time on apply, this will propagate to other modules
this.currentYear.syncTime().catch(Logger.error);
}
+ } else if(dataType && (dataType === 'dawn' || dataType === 'midday' || dataType === 'dusk' || dataType === 'midnight')){
+ this.timeOfDayControlClick(dataType);
+ GameSettings.SaveCurrentDate(this.currentYear).catch(Logger.error);
+ //Sync the current time on apply, this will propagate to other modules
+ this.currentYear.syncTime(true).catch(Logger.error);
}
}
}
@@ -822,6 +827,13 @@ export default class SimpleCalendar extends Application{
this.currentYear.changeYear(isNext? 1 : -1, false, "current");
change = true;
break;
+ case 'dawn':
+ case 'midday':
+ case 'dusk':
+ case 'midnight':
+ this.timeOfDayControlClick(dataType);
+ change = true;
+ break;
}
}
if(change){
@@ -832,6 +844,67 @@ export default class SimpleCalendar extends Application{
}
}
+
+ public timeOfDayControlClick(type: string){
+ if(this.currentYear){
+ let month = this.currentYear.getMonth();
+ let day: Day | undefined;
+ switch (type){
+ case 'dawn':
+ if(month){
+ day = month.getDay();
+ if(day){
+ let sunriseTime = this.currentYear.getSunriseSunsetTime(this.currentYear.numericRepresentation, month, day, true, false);
+ if(this.currentYear.time.seconds >= sunriseTime){
+ this.currentYear.changeDay(1, 'current');
+ month = this.currentYear.getMonth();
+ if(month){
+ day = month.getDay();
+ if(day){
+ sunriseTime = this.currentYear.getSunriseSunsetTime(this.currentYear.numericRepresentation, month, day, true, false);
+ this.currentYear.time.seconds = sunriseTime;
+ }
+ }
+ } else {
+ this.currentYear.time.seconds = sunriseTime;
+ }
+ }
+ }
+ break;
+ case 'midday':
+ const halfDay = this.currentYear.time.secondsPerDay / 2;
+ if(this.currentYear.time.seconds >= halfDay){
+ this.currentYear.changeDay(1, 'current');
+ }
+ this.currentYear.time.seconds = halfDay;
+ break;
+ case 'dusk':
+ if(month){
+ day = month.getDay();
+ if(day){
+ let sunsetTime = this.currentYear.getSunriseSunsetTime(this.currentYear.numericRepresentation, month, day, false, false);
+ if(this.currentYear.time.seconds >= sunsetTime){
+ this.currentYear.changeDay(1, 'current');
+ month = this.currentYear.getMonth();
+ if(month){
+ day = month.getDay();
+ if(day){
+ sunsetTime = this.currentYear.getSunriseSunsetTime(this.currentYear.numericRepresentation, month, day, false, false);
+ this.currentYear.time.seconds = sunsetTime;
+ }
+ }
+ } else {
+ this.currentYear.time.seconds = sunsetTime;
+ }
+ }
+ }
+ break;
+ case 'midnight':
+ this.currentYear.changeTime(true, 'second', this.currentYear.time.secondsPerDay - this.currentYear.time.seconds);
+ break;
+ }
+ }
+ }
/**
* Click event for when a gm user clicks on the apply button for the current date controls
* Will attempt to save the new current date to the world settings.
@@ -1211,6 +1284,12 @@ export default class SimpleCalendar extends Application{
const newSeason = new Season(seasonData[i].name, seasonData[i].startingMonth, seasonData[i].startingDay);
const sCustColor = seasonData[i].customColor;
newSeason.color = seasonData[i].color === 'custom' && sCustColor? sCustColor : seasonData[i].color;
+ if(seasonData[i].hasOwnProperty('sunriseTime')){
+ newSeason.sunriseTime = seasonData[i].sunriseTime;
+ }
+ if(seasonData[i].hasOwnProperty('sunsetTime')){
+ newSeason.sunsetTime = seasonData[i].sunsetTime;
+ }
this.currentYear.seasons.push(newSeason);
}
}
@@ -1263,6 +1342,7 @@ export default class SimpleCalendar extends Application{
this.currentYear.time.minutesInHour = timeData.minutesInHour;
this.currentYear.time.secondsInMinute = timeData.secondsInMinute;
this.currentYear.time.gameTimeRatio = timeData.gameTimeRatio;
+ this.currentYear.time.secondsPerDay = this.currentYear.time.hoursInDay * this.currentYear.time.minutesInHour * this.currentYear.time.secondsInMinute;
if(timeData.hasOwnProperty('unifyGameAndClockPause')){
this.currentYear.time.unifyGameAndClockPause = timeData.unifyGameAndClockPause;
@@ -1272,6 +1352,10 @@ export default class SimpleCalendar extends Application{
this.currentYear.time.updateFrequency = timeData.updateFrequency;
this.currentYear.time.timeKeeper.updateFrequency = timeData.updateFrequency;
}
+
+ if(timeData.hasOwnProperty('secondsInCombatRound')){
+ this.currentYear.time.secondsInCombatRound = timeData.secondsInCombatRound;
+ }
}
} else {
Logger.error('No Current year configured, can not load time data.');
@@ -1417,9 +1501,16 @@ export default class SimpleCalendar extends Application{
const activeScene = scenes? scenes.active? scenes.active.id : null : null;
if(this.currentYear && combat.started && ((activeScene !== null && combat.scene && combat.scene.id === activeScene) || activeScene === null)){
this.currentYear.time.combatRunning = true;
+
+ //If time does not have the advanceTime property the combat was just started
if(time && time.hasOwnProperty('advanceTime')){
- Logger.debug('Combat Change Triggered');
- this.currentYear.combatChangeTriggered = true;
+ if(time.advanceTime !== 0){
+ Logger.debug('Combat Change Triggered');
+ this.currentYear.combatChangeTriggered = true;
+ } else {
+ // System does not advance time when combat rounds change, check our own settings
+ this.currentYear.processOwnCombatRoundTime(combat);
+ }
}
}
}
@@ -1465,107 +1556,11 @@ export default class SimpleCalendar extends Application{
async timeKeepingCheck(){
//If the current year is set up and the calendar is set up for time keeping and the user is the GM
if(this.currentYear && this.currentYear.generalSettings.gameWorldTimeIntegration !== GameWorldTimeIntegrations.None && GameSettings.IsGm() ){
- const importRun = GameSettings.GetImportRan();
- // If we haven't asked about the import in the past
- if(!importRun){
- const calendarWeather = (game).modules.get('calendar-weather');
- const aboutTime = (game).modules.get('about-time');
- //Ask about calendar/weather first, then about time
- if(calendarWeather && calendarWeather.active){
- Logger.debug('Calendar/Weather detected.');
- const cwD = new Dialog({
- title: GameSettings.Localize('FSC.Module.CalendarWeather.Title'),
- content: GameSettings.Localize('FSC.Module.CalendarWeather.Message'),
- buttons:{
- import: {
- label: GameSettings.Localize('FSC.Module.Import'),
- callback: this.moduleImportClick.bind(this, 'calendar-weather')
- },
- export: {
- label: GameSettings.Localize('FSC.Module.CalendarWeather.Export'),
- callback: this.moduleExportClick.bind(this,'calendar-weather')
- },
- no: {
- label: GameSettings.Localize('FSC.Module.NoChanges'),
- callback: this.moduleDialogNoChangeClick.bind(this)
- }
- },
- default: "no"
- });
- cwD.render(true);
- } else if(aboutTime && aboutTime.active){
- Logger.debug(`About Time detected.`);
- const cwD = new Dialog({
- title: GameSettings.Localize('FSC.Module.AboutTime.Title'),
- content: GameSettings.Localize('FSC.Module.AboutTime.Message'),
- buttons:{
- import: {
- label: GameSettings.Localize('FSC.Module.Import'),
- callback: this.moduleImportClick.bind(this, 'about-time')
- },
- export: {
- label: GameSettings.Localize('FSC.Module.AboutTime.Export'),
- callback: this.moduleExportClick.bind(this,'about-time')
- },
- no: {
- label: GameSettings.Localize('FSC.Module.NoChanges'),
- callback: this.moduleDialogNoChangeClick.bind(this)
- }
- },
- default: "no"
- });
- cwD.render(true);
- }
- }
-
//Sync the current world time with the simple calendar
await this.currentYear.syncTime();
}
}
- /**
- * Called when the import option is selection from the importing/exporting module dialog
- * @param {string} type The module
- */
- async moduleImportClick(type: string) {
- if(this.currentYear){
- if(type === 'about-time'){
- await Importer.importAboutTime(this.currentYear);
- this.updateApp();
- } else if(type === 'calendar-weather'){
- await Importer.importCalendarWeather(this.currentYear);
- this.updateApp();
- }
- await GameSettings.SetImportRan(true);
- } else {
- Logger.error('Could not export as the current year is not defined');
- }
- }
-
- /**
- * Called when the export option is selection from the importing/exporting module dialog
- * @param {string} type The module
- */
- async moduleExportClick(type: string){
- if(this.currentYear){
- if(type === 'about-time'){
- await Importer.exportToAboutTime(this.currentYear);
- } else if(type === 'calendar-weather'){
- await Importer.exportCalendarWeather(this.currentYear);
- }
- await GameSettings.SetImportRan(true);
- } else {
- Logger.error('Could not export as the current year is not defined');
- }
- }
-
- /**
- * Called when the no change dialog option is clicked for importing/exporting module data
- */
- async moduleDialogNoChangeClick(){
- await GameSettings.SetImportRan(true);
- }
-
/**
* While a note is being dragged
* @param {Event} event
diff --git a/src/classes/time.test.ts b/src/classes/time.test.ts
index a85f43c8..732936e0 100644
--- a/src/classes/time.test.ts
+++ b/src/classes/time.test.ts
@@ -17,7 +17,7 @@ describe('Time Tests', () => {
});
test('Properties', () => {
- expect(Object.keys(t).length).toBe(10); //Make sure no new properties have been added
+ expect(Object.keys(t).length).toBe(11); //Make sure no new properties have been added
expect(t.hoursInDay).toBe(24);
expect(t.minutesInHour).toBe(60);
expect(t.secondsInMinute).toBe(60);
@@ -28,6 +28,7 @@ describe('Time Tests', () => {
expect(t.combatRunning).toBe(false);
expect(t.updateFrequency).toBe(1);
expect(t.unifyGameAndClockPause).toBe(false)
+ expect(t.secondsInCombatRound).toBe(6);
});
test('Clone', () => {
diff --git a/src/classes/time.ts b/src/classes/time.ts
index d36163a3..ec3bc6c6 100644
--- a/src/classes/time.ts
+++ b/src/classes/time.ts
@@ -21,6 +21,11 @@ export default class Time {
* @type {number}
*/
secondsInMinute: number;
+ /**
+ * How many seconds pass during a single round of combat
+ * @type {number}
+ */
+ secondsInCombatRound: number;
/**
* The ratio at which to advance game time while real time passes, ratio of 1 is the same, ratio of 2 is twice as fast
* @type {number}
@@ -63,6 +68,7 @@ export default class Time {
this.hoursInDay = hoursInDay;
this.minutesInHour = minutesInHour;
this.secondsInMinute = secondsInMinute;
+ this.secondsInCombatRound = 6;
this.gameTimeRatio = 1;
this.secondsPerDay = this.hoursInDay * this.minutesInHour * this.secondsInMinute;
@@ -75,6 +81,7 @@ export default class Time {
*/
clone() {
const t = new Time(this.hoursInDay, this.minutesInHour, this.secondsInMinute);
+ t.secondsInCombatRound = this.secondsInCombatRound;
t.seconds = this.seconds;
t.gameTimeRatio = this.gameTimeRatio;
t.combatRunning = this.combatRunning;
diff --git a/src/classes/utilities.test.ts b/src/classes/utilities.test.ts
index 5e003489..b31049eb 100644
--- a/src/classes/utilities.test.ts
+++ b/src/classes/utilities.test.ts
@@ -83,13 +83,12 @@ describe('Utilities Class Tests', () => {
hour: 0,
minute: 0
};
-
- expect(Utilities.FormatTime(dateToCheck)).toBe('');
- dateToCheck.allDay = false;
- expect(Utilities.FormatTime(dateToCheck)).toBe('00:00');
+ expect(Utilities.FormatTime(dateToCheck.hour, dateToCheck.minute, false)).toBe('00:00');
dateToCheck.hour = 10;
dateToCheck.minute = 15;
- expect(Utilities.FormatTime(dateToCheck)).toBe('10:15');
+ expect(Utilities.FormatTime(dateToCheck.hour, dateToCheck.minute, false)).toBe('10:15');
+ expect(Utilities.FormatTime(dateToCheck.hour, dateToCheck.minute, 0)).toBe('10:15:00');
+ expect(Utilities.FormatTime(dateToCheck.hour, dateToCheck.minute, 12)).toBe('10:15:12');
});
test('Get Moon Phase Icon', () => {
diff --git a/src/classes/utilities.ts b/src/classes/utilities.ts
index ede92ee4..c24fc474 100644
--- a/src/classes/utilities.ts
+++ b/src/classes/utilities.ts
@@ -70,20 +70,29 @@ export default class Utilities{
}
/**
- * Formats an hour and minute to include pre padded 0's
- * @param date
+ * Formats an hour, minute and optionally second to include pre padded 0's
+ * @param {Number} hour
+ * @param {Number} minute
+ * @param {Number|Boolean} second
*/
- public static FormatTime(date: SCDateSelector.Date){
+ public static FormatTime(hour: number, minute: number, second: number | false){
let text = '';
- if(!date.allDay){
- let sHour: string | number = date.hour;
- let sMinute: string | number = date.minute;
- if(sHour < 10){
- sHour = `0${sHour}`;
- }
- if(sMinute < 10){
- sMinute = `0${sMinute}`;
+ let sHour = hour.toString();
+ let sMinute = minute.toString()
+ if(hour < 10){
+ sHour = `0${hour}`;
+ }
+ if(minute < 10){
+ sMinute = `0${minute}`;
+ }
+
+ if(second !== false){
+ let sSecond = second.toString();
+ if(second < 10){
+ sSecond = `0${second}`;
}
+ text = `${sHour}:${sMinute}:${sSecond}`;
+ } else {
text = `${sHour}:${sMinute}`;
}
return text;
diff --git a/src/classes/year.test.ts b/src/classes/year.test.ts
index a336caf7..4fdf7e41 100644
--- a/src/classes/year.test.ts
+++ b/src/classes/year.test.ts
@@ -12,13 +12,21 @@ import "../../__mocks__/hooks";
import Year from "./year";
import Month from "./month";
import {Weekday} from "./weekday";
-import {GameSystems, GameWorldTimeIntegrations, LeapYearRules, TimeKeeperStatus, YearNamingRules} from "../constants";
+import {
+ GameSystems,
+ GameWorldTimeIntegrations,
+ LeapYearRules,
+ PredefinedCalendars,
+ TimeKeeperStatus,
+ YearNamingRules
+} from "../constants";
import LeapYear from "./leap-year";
import Season from "./season";
import Moon from "./moon";
import SimpleCalendar from "./simple-calendar";
import {Note} from "./note";
import {SimpleCalendarConfiguration} from "./simple-calendar-configuration";
+import PredefinedCalendar from "./predefined-calendar";
describe('Year Class Tests', () => {
let year: Year;
@@ -1066,9 +1074,20 @@ describe('Year Class Tests', () => {
test('Get Season', () => {
year.months.push(month);
year.months.push(new Month('Month 2', 2, 0, 20));
- year.seasons.push(new Season('Spring', 3, 5));
+ year.months.push(new Month('Month 3', 3, 0, 20));
+ year.seasons.push(new Season('Spring', 1, 10));
+ year.seasons.push(new Season('Summer', 2, 10));
+ year.seasons.push(new Season('Fall', 3, 10));
+ year.seasons.push(new Season('Winter', 3, 18));
let data = year.getSeason(0, 1);
+ expect(data.name).toBe('Winter');
+ data = year.getSeason(2, 9);
+ expect(data.name).toBe('Summer');
+
+ year.seasons[0].startingMonth = -1;
+ data = year.getSeason(0, 1);
+ expect(data.name).toBe('Spring');
});
test('Get Year Name', () => {
@@ -1091,4 +1110,53 @@ describe('Year Class Tests', () => {
});
+ test('Process Own Combat Round Time', () => {
+ PredefinedCalendar.setToPredefined(year, PredefinedCalendars.Gregorian);
+ let curTime = year.time.seconds;
+ year.processOwnCombatRoundTime({});
+ expect(year.time.seconds).toBe(curTime + year.time.secondsInCombatRound);
+
+ //@ts-ignore
+ game.user.isGM = true;
+ curTime = year.time.seconds;
+ //@ts-ignore
+ year.processOwnCombatRoundTime({round: 2, previous: {round: 1}});
+ expect(year.time.seconds).toBe(curTime + year.time.secondsInCombatRound);
+
+ curTime = year.time.seconds;
+ //@ts-ignore
+ year.processOwnCombatRoundTime({round: 2, previous: {round: 2}});
+ expect(year.time.seconds).toBe(curTime);
+ //@ts-ignore
+ game.user.isGM = false;
+ });
+
+ test('Get Sunrise Sunset Time', () => {
+ year.months.push(month);
+ let sunrise = year.getSunriseSunsetTime(year.numericRepresentation, month, month.days[0]);
+ expect(sunrise).toBe(0);
+
+ PredefinedCalendar.setToPredefined(year, PredefinedCalendars.Gregorian);
+
+ SimpleCalendar.instance = new SimpleCalendar();
+ SimpleCalendar.instance.currentYear = year;
+
+ sunrise = year.getSunriseSunsetTime(year.numericRepresentation, year.months[0], year.months[0].days[0], true, false);
+ expect(sunrise).toBe(21600);
+
+ sunrise = year.getSunriseSunsetTime(year.numericRepresentation, year.months[2], year.months[2].days[19], false, false);
+ expect(sunrise).toBe(64800);
+
+ sunrise = year.getSunriseSunsetTime(year.numericRepresentation, year.months[3], year.months[3].days[19], true, true);
+ expect(sunrise).toBe(1618898400);
+
+ sunrise = year.getSunriseSunsetTime(year.numericRepresentation, year.months[11], year.months[11].days[21], true, false);
+ expect(sunrise).toBe(21600);
+
+ year.seasons[1].startingMonth = 3;
+ year.seasons[1].startingDay = 29;
+ sunrise = year.getSunriseSunsetTime(year.numericRepresentation, year.months[0], year.months[0].days[0], true, false);
+ expect(sunrise).toBe(21600);
+ });
+
});
diff --git a/src/classes/year.ts b/src/classes/year.ts
index cbd82cf7..f103e06c 100644
--- a/src/classes/year.ts
+++ b/src/classes/year.ts
@@ -19,6 +19,9 @@ import {Note} from "./note";
import SimpleCalendar from "./simple-calendar";
import PF2E from "./systems/pf2e";
import Utilities from "./utilities";
+import Day from "./day";
+import DateSelector from "./date-selector";
+import API from "./api";
/**
* Class for representing a year
@@ -1009,16 +1012,19 @@ export default class Year {
let season = new Season('', 1, 1);
if(day > 0 && monthIndex >= 0){
let currentSeason: Season | null = null;
- for(let i = 0; i < this.seasons.length; i++){
- const seasonMonthIndex = this.months.findIndex(m => m.numericRepresentation === this.seasons[i].startingMonth);
- if(seasonMonthIndex === monthIndex && this.seasons[i].startingDay <= day){
- currentSeason = this.seasons[i];
+
+ const sortedSeasons = this.seasons.sort((a, b) => { return a.startingMonth - b.startingMonth || a.startingDay - b.startingDay; });
+
+ for(let i = 0; i < sortedSeasons.length; i++){
+ const seasonMonthIndex = this.months.findIndex(m => m.numericRepresentation === sortedSeasons[i].startingMonth);
+ if(seasonMonthIndex === monthIndex && sortedSeasons[i].startingDay <= day){
+ currentSeason = sortedSeasons[i];
} else if (seasonMonthIndex < monthIndex){
- currentSeason = this.seasons[i];
+ currentSeason = sortedSeasons[i];
}
}
if(currentSeason === null){
- currentSeason = this.seasons[this.seasons.length - 1];
+ currentSeason = sortedSeasons[sortedSeasons.length - 1];
}
if(currentSeason){
@@ -1056,4 +1062,83 @@ export default class Year {
return name;
}
+
+ /**
+ * If we have determined that the system does not change the world time when a combat round is changed we run this function to update the time by the set amount.
+ * @param {Combat} combat The current active combat
+ */
+ processOwnCombatRoundTime(combat: Combat){
+ let roundSeconds = this.time.secondsInCombatRound;
+ let roundsPassed = 1;
+
+ if(combat.hasOwnProperty('previous') && combat['previous'].round){
+ roundsPassed = combat.round - combat['previous'].round;
+ }
+ if(roundSeconds !== 0 && roundsPassed !== 0){
+ const parsedDate = this.secondsToDate(this.toSeconds() + (roundSeconds * roundsPassed));
+ this.updateTime(parsedDate);
+ // If the current player is the GM then we need to save this new value to the database
+ // Since the current date is updated this will trigger an update on all players as well
+ if(GameSettings.IsGm() && SimpleCalendar.instance.primary){
+ GameSettings.SaveCurrentDate(this).catch(Logger.error);
+ }
+ }
+ }
+
+ /**
+ * Calculates the sunrise or sunset time for the passed in date, based on the the season setup
+ * @param {number} year The year of the date
+ * @param {Month} month The month object of the date
+ * @param {Day} day The day object of the date
+ * @param {boolean} [sunrise=true] If to calculate the sunrise or sunset
+ * @param {boolean} [calculateTimestamp=true] If to add the date timestamp to the sunrise/sunset time
+ */
+ getSunriseSunsetTime(year: number, month: Month, day: Day, sunrise: boolean = true, calculateTimestamp: boolean = true){
+ const monthIndex = this.months.findIndex(m => m.numericRepresentation === month.numericRepresentation);
+ const dayIndex = month.days.findIndex(d => d.numericRepresentation === day.numericRepresentation);
+
+ const sortedSeasons = this.seasons.sort((a, b) => { return a.startingMonth - b.startingMonth || a.startingDay - b.startingDay; });
+ let seasonIndex = sortedSeasons.length - 1;
+ for(let i = 0; i < sortedSeasons.length; i++){
+ const seasonMonthIndex = this.months.findIndex(m => m.numericRepresentation === sortedSeasons[i].startingMonth);
+ if(seasonMonthIndex === monthIndex && sortedSeasons[i].startingDay <= day.numericRepresentation){
+ seasonIndex = i;
+ } else if (seasonMonthIndex < monthIndex){
+ seasonIndex = i;
+ }
+ }
+ const nextSeasonIndex = (seasonIndex + 1) % this.seasons.length;
+ if(seasonIndex < sortedSeasons.length && nextSeasonIndex < sortedSeasons.length){
+ let season = sortedSeasons[seasonIndex];
+ const nextSeason = sortedSeasons[nextSeasonIndex];
+ let seasonYear = year;
+ let nextSeasonYear = seasonYear;
+
+ //If the current season is the last season of the year we need to check to see if the year for this season is the year before the current date
+ if(seasonIndex === sortedSeasons.length - 1){
+ if(this.months[monthIndex].numericRepresentation < sortedSeasons[seasonIndex].startingMonth || (sortedSeasons[seasonIndex].startingMonth === this.months[monthIndex].numericRepresentation && this.months[monthIndex].days[dayIndex].numericRepresentation < sortedSeasons[seasonIndex].startingDay)){
+ seasonYear = year - 1;
+ }
+ nextSeasonYear = seasonYear + 1
+ }
+ const daysBetweenSeasonStartAndDay = DateSelector.DaysBetweenDates(
+ { year: seasonYear, month: season.startingMonth, day: season.startingDay, allDay: false, hour: 0, minute: 0 },
+ { year: year, month: this.months[monthIndex].numericRepresentation, day: this.months[monthIndex].days[dayIndex].numericRepresentation, hour: 0, minute: 0, allDay: false }
+ );
+ const daysBetweenSeasons = DateSelector.DaysBetweenDates(
+ { year: seasonYear, month: season.startingMonth, day: season.startingDay, allDay: false, hour: 0, minute: 0 },
+ { year: nextSeasonYear, month: nextSeason.startingMonth, day: nextSeason.startingDay, allDay: false, hour: 0, minute: 0 }
+ );
+ const diff = sunrise? nextSeason.sunriseTime - season.sunriseTime : nextSeason.sunsetTime - season.sunsetTime;
+ const averageChangePerDay = diff / daysBetweenSeasons;
+ const sunriseChangeForDay = daysBetweenSeasonStartAndDay * averageChangePerDay;
+ const finalSunriseTime = Math.round((sunrise? season.sunriseTime : season.sunsetTime) + sunriseChangeForDay);
+ if(calculateTimestamp){
+ return API.dateToTimestamp({ year: year, month: monthIndex, day: dayIndex, hour: 0, minute: 0, second: 0 }) + finalSunriseTime;
+ } else {
+ return finalSunriseTime;
+ }
+ }
+ return 0;
+ }
}
diff --git a/src/constants.ts b/src/constants.ts
index 3c21c3e8..26c4b512 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -23,7 +23,6 @@ export enum SettingNames {
LeapYearRule = 'leap-year-rule',
TimeConfiguration = 'time-configuration',
GeneralConfiguration = 'general-configuration',
- ImportRan = 'import-ran',
SeasonConfiguration = 'season-configuration',
MoonConfiguration = 'moon-configuration',
NoteCategories = 'note-categories'
diff --git a/src/index.ts b/src/index.ts
index e3fbabf0..6f26f3c1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -28,3 +28,5 @@ Hooks.on("deleteCombat", SimpleCalendar.instance.combatDelete.bind(SimpleCalenda
Hooks.on("pauseGame", SimpleCalendar.instance.gamePaused.bind(SimpleCalendar.instance));
Logger.debugMode = false;
+
+//Hooks.on(SimpleCalendarHooks.DateTimeChange, (...args: any) => {console.log(...args);});
diff --git a/src/interfaces.test.ts b/src/interfaces.test.ts
index 369c1c22..e64a1aa0 100644
--- a/src/interfaces.test.ts
+++ b/src/interfaces.test.ts
@@ -269,14 +269,15 @@ describe('Interface Tests', () => {
});
test('Time Configuration', () => {
- const tc: TimeConfig = {gameTimeRatio:1, secondsInMinute: 0, minutesInHour: 0, hoursInDay: 0, unifyGameAndClockPause: false, updateFrequency: 1};
- expect(Object.keys(tc).length).toBe(6); //Make sure no new properties have been added
+ const tc: TimeConfig = {gameTimeRatio:1, secondsInMinute: 0, minutesInHour: 0, hoursInDay: 0, secondsInCombatRound: 6, unifyGameAndClockPause: false, updateFrequency: 1};
+ expect(Object.keys(tc).length).toBe(7); //Make sure no new properties have been added
expect(tc.gameTimeRatio).toBe(1);
expect(tc.secondsInMinute).toBe(0);
expect(tc.minutesInHour).toBe(0);
expect(tc.hoursInDay).toBe(0);
expect(tc.updateFrequency).toBe(1);
expect(tc.unifyGameAndClockPause).toBe(false);
+ expect(tc.secondsInCombatRound).toBe(6);
});
test('Time Template', () => {
@@ -287,16 +288,15 @@ describe('Interface Tests', () => {
});
test('Season Template', () => {
- const st: SeasonTemplate = {name: '', startingMonth: 1, startingDay: 1, color: '', dayList: []};
+ const st: SeasonTemplate = {name: '', startingMonth: 1, startingDay: 1, color: '', startDateSelectorId: '', sunriseSelectorId: ''};
expect(st.name).toBe('');
expect(st.color).toBe('');
expect(st.startingMonth).toBe(1);
expect(st.startingDay).toBe(1);
- expect(st.dayList).toStrictEqual([]);
});
test('Season Configuration', () => {
- const sc: SeasonConfiguration = {name: '', startingMonth: 1, startingDay: 1, color: '', customColor: ''};
+ const sc: SeasonConfiguration = {name: '', startingMonth: 1, startingDay: 1, color: '', customColor: '', sunriseTime: 0, sunsetTime: 0};
expect(sc.name).toBe('');
expect(sc.color).toBe('');
expect(sc.customColor).toBe('');
diff --git a/src/interfaces.ts b/src/interfaces.ts
index 07b6a822..c594f900 100644
--- a/src/interfaces.ts
+++ b/src/interfaces.ts
@@ -272,6 +272,7 @@ export interface TimeConfig {
hoursInDay: number;
minutesInHour: number;
secondsInMinute: number;
+ secondsInCombatRound: number;
gameTimeRatio: number;
unifyGameAndClockPause: boolean;
updateFrequency: number;
@@ -294,7 +295,8 @@ export interface SeasonTemplate {
startingMonth: number;
startingDay: number;
color: string;
- dayList: DayTemplate[];
+ startDateSelectorId: string;
+ sunriseSelectorId: string;
}
/**
@@ -304,6 +306,8 @@ export interface SeasonConfiguration {
name: string;
startingMonth: number;
startingDay: number;
+ sunriseTime: number;
+ sunsetTime: number;
color: string;
customColor?: string;
}
@@ -440,9 +444,17 @@ export namespace SCDateSelector {
export interface Options {
placeHolderText?: string;
onDateSelect?: Function;
- rangeSelect?: boolean;
+ dateRangeSelect?: boolean;
+ timeRangeSelect?: boolean;
+ showYear?: boolean;
+ inputMatchCalendarWidth?: boolean;
showDate: boolean;
showTime: boolean;
+ startDate?: DateTimeParts,
+ endDate?: DateTimeParts,
+ allDay?: boolean
+ timeDelimiter?: string;
+ showTimeLabel?: boolean;
}
export interface Date{
diff --git a/src/lang/en.json b/src/lang/en.json
index 6c99b6e0..1e622365 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -26,6 +26,10 @@
"FSC.Back": "Back",
"FSC.Clear": "Clear",
"FSC.Random": "Random",
+ "FSC.Midnight": "Midnight",
+ "FSC.Dawn": "Dawn",
+ "FSC.Midday": "Midday",
+ "FSC.Dusk": "Dusk",
"FSC.ShowAdvanced": "Show Advanced",
"FSC.HideAdvanced": "Hide Advanced",
"FSC.DateControls": "Date Controls",
@@ -179,10 +183,8 @@
"FSC.Configuration.Year.Seasons": "Seasons",
"FSC.Configuration.Season.Name": "Season Name",
"FSC.Configuration.Season.NameHelp": "The name of this season.",
- "FSC.Configuration.Season.StartingMonth": "Starting Month",
- "FSC.Configuration.Season.StartingMonthHelp": "The month when this season starts every year.",
- "FSC.Configuration.Season.StartingDay": "Starting Day",
- "FSC.Configuration.Season.StartingDayHelp": "The day of the month when this season starts every year.",
+ "FSC.Configuration.Season.StartingDate": "Starting Date",
+ "FSC.Configuration.Season.StartingDateHelp": "The month and day when this season starts every year.",
"FSC.Configuration.Season.Color": "Color",
"FSC.Configuration.Season.ColorHelp": "The color to associate with this season.",
"FSC.Configuration.Season.ColorWhite": "White",
@@ -194,6 +196,8 @@
"FSC.Configuration.Season.ColorCustomHelp": "Set a custom hex value color for the season.",
"FSC.Configuration.Season.RemoveAll": "Remove All Seasons",
"FSC.Configuration.Season.Add": "Add New Season",
+ "FSC.Configuration.Season.SunriseSunset": "Sunrise/Sunset Time",
+ "FSC.Configuration.Season.SunriseSunsetHelp": "The time of day the sun rises and sun sets for the first day of the season.",
"FSC.Configuration.Month.Title": "Month Settings",
"FSC.Configuration.Month.Name": "Month Name",
"FSC.Configuration.Month.NameHelp": "The text name of this month.",
@@ -244,6 +248,8 @@
"FSC.Configuration.Time.MinutesInHourHelp": "How many minutes make up a single hour.",
"FSC.Configuration.Time.SecondsInMinute": "Seconds in a Minute",
"FSC.Configuration.Time.SecondsInMinuteHelp": "How many seconds make up a single minute.",
+ "FSC.Configuration.Time.SecondsInCombatRound": "Seconds per Combat Round",
+ "FSC.Configuration.Time.SecondsInCombatRoundHelp": "How many seconds pass during 1 round of combat. This is only applied if the current system does not increment time during combat rounds!",
"FSC.Configuration.Time.GameTimeRatio": "Game Seconds Per Real Life Seconds",
"FSC.Configuration.Time.GameTimeRatioHelp": "How many seconds pass in game for every second that passes in real time.",
"FSC.Configuration.Time.Options": "Time Options",
diff --git a/src/lang/es.json b/src/lang/es.json
index f2870d79..7c35e96c 100644
--- a/src/lang/es.json
+++ b/src/lang/es.json
@@ -1,4 +1,7 @@
{
+ "I18N.LANGUAGE": "Español",
+ "I18N.MAINTAINERS": "areymoreno, @Viriato139ac#0342",
+
"FSC.Title": "Simple Calendar",
"FSC.Compact": "Compacto",
"FSC.Full": "Integro",
@@ -6,7 +9,12 @@
"FSC.One": "1",
"FSC.Five": "5",
"FSC.Thirty": "30",
+ "FSC.OrdinalSuffix.st": "o",
+ "FSC.OrdinalSuffix.nd": "o",
+ "FSC.OrdinalSuffix.rd": "o",
+ "FSC.OrdinalSuffix.th": "o",
"FSC.ButtonTitle": "Calendario",
+ "FSC.AllDay": "Todo el día",
"FSC.Day": "Día",
"FSC.Days": "Días",
"FSC.Month": "Mes",
@@ -19,11 +27,13 @@
"FSC.SecondShorthand": "seg",
"FSC.Forward": "Avanzar",
"FSC.Back": "Regresar",
+ "FSC.Clear": "Borrar",
+ "FSC.Random": "Al azar",
"FSC.ShowAdvanced": "Mostrar más",
"FSC.HideAdvanced": "Mostrar menos",
"FSC.DateControls": "Controles de fecha",
- "FSC.DateControlsHelp": "Utiliza estos controles para cambiar la fecha actual en tu juego.",
- "FSC.NoDateControls": "Simple Calendar ha sido configurado para que otro movil controle la fecha y la hora. Por favor, utilice este módulo para actualizar la hora o cambiar la configuración de Simple Calendars.",
+ "FSC.DateControlsHelp": "Utiliza estos controles para cambiar la fecha actual en tu juego",
+ "FSC.NoDateControls": "Simple Calendar ha sido configurado para que otro movil controle la fecha y la hora. Por favor, utilice este módulo para actualizar la hora o cambiar la configuración de Simple Calendars",
"FSC.SetCurrentDate": "Establecer la fecha actual",
"FSC.SetCurrentDateDialog.Title": "Confirmar el cambio de fecha actual",
"FSC.SetCurrentDateDialog.Content": "¡Ha seleccionado cambiar la fecha a un día que no es visible actualmente! ¿Está seguro de que quiere cambiar la fecha actual a {DATE}?",
@@ -31,6 +41,8 @@
"FSC.AdvancedOptions": "Opciones avanzadas",
"FSC.Today": "Hoy",
"FSC.Configure": "Configurar",
+ "FSC.Import": "Importar",
+ "FSC.Export": "Exportar",
"FSC.By": "Por",
"FSC.Cancel": "Cancelar",
"FSC.Edit": "Editar",
@@ -48,7 +60,7 @@
"FSC.MoveMonthBack": "Retroceder un mes",
"FSC.MoveDayBack": "Retroceder un día",
"FSC.Time.Controls": "Controles de tiempo",
- "FSC.Time.ControlsHelp": "Seleccione una unidad de tiempo para cambiar y luego use los controles para avanzar o reducir esa unidad en 1 o 5.",
+ "FSC.Time.ControlsHelp": "Seleccione una unidad de tiempo para cambiar y luego use los controles para avanzar o reducir esa unidad en 1 o 5",
"FSC.Time.Forward": "Avanzar en el tiempo",
"FSC.Time.Backward": "Retroceder en el tiempo",
"FSC.Time.Start": "Comenzar a adelantar el tiempo",
@@ -60,17 +72,26 @@
"FSC.Notes.AddNew": "Añadir nueva nota",
"FSC.Notes.NewFor": "Nueva nota para",
"FSC.Notes.Title": "Título de la nota",
- "FSC.Notes.TitleHelp": "El título de esta nota.",
+ "FSC.Notes.TitleHelp": "El título de esta nota",
+ "FSC.Notes.Date": "Fecha de la nota",
+ "FSC.Notes.DateHelp": "Fecha a la que se refiere la nota",
+ "FSC.Notes.NotPlayerVisible": "No visible por los jugadores",
"FSC.Notes.PlayerVisible": "Jugador visible",
- "FSC.Notes.PlayerVisibleHelp": "Si esta nota es visible por los jugadores o no.",
+ "FSC.Notes.PlayerVisibleHelp": "Si esta nota es visible por los jugadores o no",
+ "FSC.Notes.Reminder": "¡Recordármelo!",
+ "FSC.Notes.ReminderHelp": "Se le recordará este evento",
"FSC.Notes.Repeating": "Repetición de nota",
- "FSC.Notes.RepeatingHelp": "Si esta nota se repite semanal, mensual, anualmente o no se repite.",
+ "FSC.Notes.RepeatingHelp": "Si esta nota se repite semanal, mensual, anualmente o no se repite",
"FSC.Notes.Save": "Guardar Nota",
"FSC.Notes.Repeats": "Se repite",
"FSC.Notes.Repeat.Never": "Nunca",
"FSC.Notes.Repeat.Monthly": "Mensual",
"FSC.Notes.Repeat.Yearly": "Anual",
"FSC.Notes.Repeat.Weekly": "Semanal",
+ "FSC.Notes.Time": "Hora",
+ "FSC.Notes.DateTime.Title": "Fecha/hora de la nota",
+ "FSC.Notes.DateTime.Help": "La fecha de la nota y, opcionalmente, la hora en la que ocurre",
+ "FSC.Notes.DateTime.AllDay": "Añadir hora",
"FSC.Notes.Author": "Autor",
"FSC.Date.Sunday": "Domingo",
"FSC.Date.Monday": "Lunes",
@@ -101,169 +122,186 @@
"FSC.Moon.Phase.LastQuarter": "Cuarto Menguante",
"FSC.Moon.Phase.WaningCrescent": "Menguante",
"FSC.Configuration.Title": "Configuración del calendario",
- "FSC.Configuration.Description": "Este formulario le permite personalizar su calendario de juegos especificando el año en curso, cuántos meses, el nombre de cada mes y cuántos días tiene cada mes.",
+ "FSC.Configuration.Description": "Este formulario le permite personalizar su calendario de juegos especificando el año en curso, cuántos meses, el nombre de cada mes y cuántos días tiene cada mes",
"FSC.Configuration.Help": "¡Si necesitas ayuda para configurar el calendario, no dejes de consultar la documentación!",
"FSC.Configuration.Save": "Guardar Configuración",
"FSC.Configuration.General.Title": "Configuración general",
"FSC.Configuration.General.PreDefined": "Calendarios predefinidos",
- "FSC.Configuration.General.PreDefinedHelp": "Elija uno de los calendarios predefinidos para empezar a configurarlo más rápidamente.",
+ "FSC.Configuration.General.PreDefinedHelp": "Elija uno de los calendarios predefinidos para empezar a configurarlo más rápidamente",
"FSC.Configuration.General.GameWorldTime": "Integración del tiempo en el mundo del juego",
- "FSC.Configuration.General.GameWorldTimeHelp": "Indicar al Simple Calendar cómo integrarse con la hora del mundo del juego y responder a las actualizaciones de la hora del mundo del juego.",
- "FSC.Configuration.General.None": "Ninguna: No se relaciona con el tiempo del mundo del juego.",
- "FSC.Configuration.General.Self": "Uno mismo: Controla el tiempo del mundo del juego ignorando las actualizaciones de otros módulos.",
- "FSC.Configuration.General.ThirdParty": "Módulo de terceros: Sólo sigue las actualizaciones de la hora del mundo del juego de otros módulos.",
- "FSC.Configuration.General.Mixed": "Mixto: Actualiza el tiempo del mundo del juego y sigue las actualizaciones realizadas desde otros módulos.",
+ "FSC.Configuration.General.GameWorldTimeHelp": "Indicar al Simple Calendar cómo integrarse con la hora del mundo del juego y responder a las actualizaciones de la hora del mundo del juego",
+ "FSC.Configuration.General.None": "Ninguna: No se relaciona con el tiempo del mundo del juego",
+ "FSC.Configuration.General.Self": "Uno mismo: Controla el tiempo del mundo del juego ignorando las actualizaciones de otros módulos",
+ "FSC.Configuration.General.ThirdParty": "Módulo de terceros: Sólo sigue las actualizaciones de la hora del mundo del juego de otros módulos",
+ "FSC.Configuration.General.Mixed": "Mixto: Actualiza el tiempo del mundo del juego y sigue las actualizaciones realizadas desde otros módulos",
"FSC.Configuration.General.PF2ESync": "Pathfinder 2E: Sincronización horaria mundial",
- "FSC.Configuration.General.PF2ESyncHelp": "Esto forzará al Simple Calendar a mantener sincronizado con la hora mundial de Pathfinder 2E.",
+ "FSC.Configuration.General.PF2ESyncHelp": "Esto forzará al Simple Calendar a mantener sincronizado con la hora mundial de Pathfinder 2E",
"FSC.Configuration.General.ShowClock": "Mostrar Reloj",
- "FSC.Configuration.General.ShowClockHelp": "Si se quiere mostrar el reloj de la hora debajo del calendario, si se marca los controles para cambiar las horas, los minutos y los segundos también se mostrarán.",
+ "FSC.Configuration.General.ShowClockHelp": "Si se quiere mostrar el reloj de la hora debajo del calendario, si se marca los controles para cambiar las horas, los minutos y los segundos también se mostrarán",
"FSC.Configuration.General.PlayerAddNotes": "Añadir notas",
- "FSC.Configuration.General.PlayerAddNotesHelp": "Los roles marcados podrán añadir notas a la agenda.",
+ "FSC.Configuration.General.PlayerAddNotesHelp": "Los roles marcados podrán añadir notas a la agenda",
+ "FSC.Configuration.General.PlayerReorderNotes": "Reordenar notas",
+ "FSC.Configuration.General.PlayerReorderNotesHelp": "Los roles marcados podrán reordenar las notas de un día",
"FSC.Configuration.General.QuickSetup": "Configuración rápida",
"FSC.Configuration.General.Notes": "Notas",
+ "FSC.Configuration.General.ImportExport.Title": "Importar/Exportar",
+ "FSC.Configuration.General.ImportExport.SCConfig": "Importar/Exportar configuración de calendario",
+ "FSC.Configuration.General.ImportExport.SCConfigHelp": "Para exportar la configuración actual del calendario Simple Calendar y compartirlo o importarlo en otro mundo",
"FSC.Configuration.General.ThirdPartyModule": "Importación/exportación de módulos de terceros",
- "FSC.Configuration.General.Permissions.Note": "Aquí se pueden ajustar los permisos para varias interacciones con Simple Calendar en función de los roles de Foundry. Los Game Masters siempre tendrán estos permisos.",
+ "FSC.Configuration.General.Permissions.Note": "Aquí se pueden ajustar los permisos para varias interacciones con Simple Calendar en función de los roles de Foundry. Los Game Masters siempre tendrán estos permisos",
"FSC.Configuration.General.CalendarPlayerVisible": "Ver Calendario",
- "FSC.Configuration.General.CalendarPlayerVisibleHelp": "Los roles marcados podrán abrir Simple Calendar.",
+ "FSC.Configuration.General.CalendarPlayerVisibleHelp": "Los roles marcados podrán abrir Simple Calendar",
"FSC.Configuration.General.PlayersChangeDateTime": "Cambiar la fecha y la hora",
"FSC.Configuration.General.PlayersChangeDateTimeHelp": "Los roles marcados podrán cambiar la fecha y la hora de Simple Calendar",
"FSC.Configuration.Notes.Title": "Ajustes de nota",
+ "FSC.Configuration.Notes.NoteCategories": "Categorías de notas",
+ "FSC.Configuration.NoteCategories.Name": "Nombre de la categoría de notas",
+ "FSC.Configuration.NoteCategories.NameHelp": "El nombre que se muestra en esta categoría de notas",
+ "FSC.Configuration.NoteCategories.Color": "Color de la categoría de notas",
+ "FSC.Configuration.NoteCategories.ColorHelp": "El color asociado a la categoría de notas",
+ "FSC.Configuration.NoteCategories.Add": "Añadir categoría de notas",
+ "FSC.Configuration.NoteCategories.RemoveAll": "Borrar todas las categorías de notas",
+ "FSC.Configuration.Notes.NoteCategoriesHelp": "Seleccione todas las categorías asociadas con esta nota",
"FSC.Configuration.Year.Title": "Ajustes de Año",
"FSC.Configuration.Year.Current": "Año Actual",
- "FSC.Configuration.Year.CurrentHelp": "El año actual en el que se desarrolla el juego. Esto también se puede cambiar con los controles de fecha.",
+ "FSC.Configuration.Year.CurrentHelp": "El año actual en el que se desarrolla el juego. Esto también se puede cambiar con los controles de fecha",
"FSC.Configuration.Year.Prefix": "Prefijo del año",
- "FSC.Configuration.Year.PrefixHelp": "Texto que aparece antes del año.",
+ "FSC.Configuration.Year.PrefixHelp": "Texto que aparece antes del año",
"FSC.Configuration.Year.Postfix": "Sufijo deñ año",
- "FSC.Configuration.Year.PostfixHelp": "Texto que aparece después del año.",
+ "FSC.Configuration.Year.PostfixHelp": "Texto que aparece después del año",
"FSC.Configuration.Year.YearZero": "Año cero",
- "FSC.Configuration.Year.YearZeroHelp": "Este es el año que se considera el año cero para calcular el tiempo transcurrido. Por lo general, no será necesario modificarlo.",
+ "FSC.Configuration.Year.YearZeroHelp": "Este es el año que se considera el año cero para calcular el tiempo transcurrido. Por lo general, no será necesario modificarlo",
"FSC.Configuration.Year.YearNames": "Nombres de los años",
"FSC.Configuration.Year.YearName": "Nombre del año",
"FSC.Configuration.Year.YearNameAdd": "Añadir el nombre del nuevo año",
"FSC.Configuration.Year.YearNameRemove": "Eliminar los nombres de todos los años",
"FSC.Configuration.Year.YearNamesStart": "Año de inicio para los nombres",
- "FSC.Configuration.Year.YearNamesStartHelp": "El año en que comienza el nombre del primer año de la lista.",
+ "FSC.Configuration.Year.YearNamesStartHelp": "El año en que comienza el nombre del primer año de la lista",
"FSC.Configuration.Year.YearNameBehaviour": "Orden de los nombres de los años",
- "FSC.Configuration.Year.YearNameBehaviourHelp": "Cómo determinar el orden de los nombres de los años.",
+ "FSC.Configuration.Year.YearNameBehaviourHelp": "Cómo determinar el orden de los nombres de los años",
"FSC.Configuration.Year.Seasons": "Estaciones",
"FSC.Configuration.Season.Name": "Nombre de la estación",
- "FSC.Configuration.Season.NameHelp": "El nombre de esta estación.",
+ "FSC.Configuration.Season.NameHelp": "El nombre de esta estación",
"FSC.Configuration.Season.StartingMonth": "Mes de inicio",
- "FSC.Configuration.Season.StartingMonthHelp": "El mes en el que comienza esta estación cada año.",
+ "FSC.Configuration.Season.StartingMonthHelp": "El mes en el que comienza esta estación cada año",
"FSC.Configuration.Season.StartingDay": "Día de inicio",
- "FSC.Configuration.Season.StartingDayHelp": "El día en el que comienza esta estación cada año.",
+ "FSC.Configuration.Season.StartingDayHelp": "El día en el que comienza esta estación cada año",
"FSC.Configuration.Season.Color": "Color",
- "FSC.Configuration.Season.ColorHelp": "El color a asociado con esta estación.",
+ "FSC.Configuration.Season.ColorHelp": "El color a asociado con esta estación",
"FSC.Configuration.Season.ColorWhite": "Blanco",
"FSC.Configuration.Season.ColorSpring": "Primavera",
"FSC.Configuration.Season.ColorSummer": "Verano",
"FSC.Configuration.Season.ColorFall": "Otoño",
"FSC.Configuration.Season.ColorWinter": "Invierno",
"FSC.Configuration.Season.ColorCustom": "Color personalizado",
- "FSC.Configuration.Season.ColorCustomHelp": "Establezca un color de valor hexadecimal personalizado para la estación.",
+ "FSC.Configuration.Season.ColorCustomHelp": "Establezca un color de valor hexadecimal personalizado para la estación",
"FSC.Configuration.Season.RemoveAll": "Eliminar todas las estaciones",
"FSC.Configuration.Season.Add": "Añadir estación",
"FSC.Configuration.Month.Title": "Ajustes de mes",
"FSC.Configuration.Month.Name": "Nombre del mes",
- "FSC.Configuration.Month.NameHelp": "El nombre del texto de este mes.",
+ "FSC.Configuration.Month.NameHelp": "El nombre del texto de este mes",
"FSC.Configuration.Month.Days": "Número de días",
- "FSC.Configuration.Month.DaysHelp": "El número de días que componen este mes.",
+ "FSC.Configuration.Month.DaysHelp": "El número de días que componen este mes",
"FSC.Configuration.Month.Intercalary": "Mes intercalado",
- "FSC.Configuration.Month.IntercalaryHelp": "Si este mes debe ser considerado como un mes intercalado o no.",
+ "FSC.Configuration.Month.IntercalaryHelp": "Si este mes debe ser considerado como un mes intercalado o no",
"FSC.Configuration.Month.IntercalaryInclude": "Incluir el mes intercalado en el recuento total de días",
- "FSC.Configuration.Month.IntercalaryIncludeHelp": "If checked the days that make up the intercalary month will be included in the total number of days in a year.",
+ "FSC.Configuration.Month.IntercalaryIncludeHelp": "If checked the days that make up the intercalary month will be included in the total number of days in a year",
"FSC.Configuration.Month.DayOffset": "Compensación por día",
"FSC.Configuration.Month.DayOffsetHelp": "La cantidad para compensar el número del día. Se utiliza si se quiere comenzar un mes en 2 en lugar de 1",
"FSC.Configuration.Month.Number": "Número de mes",
- "FSC.Configuration.Month.NumberHelp": "La representación numérica de este mes.",
+ "FSC.Configuration.Month.NumberHelp": "La representación numérica de este mes",
"FSC.Configuration.Month.StartingWeekDay": "Día en que comienza la semana",
- "FSC.Configuration.Month.StartingWeekDayHelp": "Choose which day of the week this month will always start on, or leave as default to let the calendar figure out the appropriate weekday.",
+ "FSC.Configuration.Month.StartingWeekDayHelp": "Choose which day of the week this month will always start on, or leave as default to let the calendar figure out the appropriate weekday",
"FSC.Configuration.Month.Remove": "Remove",
"FSC.Configuration.Month.RemoveAll": "Remove All Months",
"FSC.Configuration.Month.Add": "Add New Month",
"FSC.Configuration.Months": "Months",
"FSC.Configuration.Weekday.Title": "Weekday Settings",
"FSC.Configuration.Weekday.ShowHeadings": "Show Weekday Headings",
- "FSC.Configuration.Weekday.ShowHeadingsHelp": "If to show the weekday headings on the calendar.",
+ "FSC.Configuration.Weekday.ShowHeadingsHelp": "If to show the weekday headings on the calendar",
"FSC.Configuration.Weekday.Name": "Weekday Name",
- "FSC.Configuration.Weekday.NameHelp": "The text name of this day of the week.",
+ "FSC.Configuration.Weekday.NameHelp": "The text name of this day of the week",
"FSC.Configuration.Weekday.Add": "Add New Weekday",
"FSC.Configuration.Weekday.RemoveAll": "Remove All Weekdays",
"FSC.Configuration.Weekdays": "Weekdays",
"FSC.Configuration.Weekday.Options": "Weekday Options",
"FSC.Configuration.Weekday.FirstWeekDay": "Starting Week Day",
- "FSC.Configuration.Weekday.FirstWeekDayHelp": "This sets the day of the week that the first day of year 0 starts on.",
+ "FSC.Configuration.Weekday.FirstWeekDayHelp": "This sets the day of the week that the first day of year 0 starts on",
"FSC.Configuration.DefaultNoteVisibility": "Note Default Player Visibility",
"FSC.Configuration.DefaultNoteVisibilityHint": "For new notes, if by default the player visibility option is checked or not",
"FSC.Configuration.LeapYear.Title": "Leap Year Settings",
"FSC.Configuration.LeapYear.Rule": "Leap Year Rule",
- "FSC.Configuration.LeapYear.RuleHelp": "The rules to follow when determining leap years.",
+ "FSC.Configuration.LeapYear.RuleHelp": "The rules to follow when determining leap years",
"FSC.Configuration.LeapYear.CustomMod": "When Leap Years Happen",
- "FSC.Configuration.LeapYear.CustomModHelp": "Every x number of years is a leap year.",
+ "FSC.Configuration.LeapYear.CustomModHelp": "Every x number of years is a leap year",
"FSC.Configuration.LeapYear.Rules.None": "None",
"FSC.Configuration.LeapYear.Rules.Gregorian": "Gregorian",
"FSC.Configuration.LeapYear.Rules.Custom": "Custom",
"FSC.Configuration.LeapYear.Days": "Number of Days in a Leap Year",
- "FSC.Configuration.LeapYear.DaysHelp": "The number of days that make up this month during a leap year.",
+ "FSC.Configuration.LeapYear.DaysHelp": "The number of days that make up this month during a leap year",
"FSC.Configuration.LeapYear.Options": "Leap Year Options",
"FSC.Configuration.Time.Title": "Time Settings",
"FSC.Configuration.Time.HoursInDay": "Hours in a Day",
- "FSC.Configuration.Time.HoursInDayHelp": "How many hours make up a single day.",
+ "FSC.Configuration.Time.HoursInDayHelp": "How many hours make up a single day",
"FSC.Configuration.Time.MinutesInHour": "Minutes in a Hour",
- "FSC.Configuration.Time.MinutesInHourHelp": "How many minutes make up a single hour.",
+ "FSC.Configuration.Time.MinutesInHourHelp": "How many minutes make up a single hour",
"FSC.Configuration.Time.SecondsInMinute": "Seconds in a Minute",
- "FSC.Configuration.Time.SecondsInMinuteHelp": "How many seconds make up a single minute.",
+ "FSC.Configuration.Time.SecondsInMinuteHelp": "How many seconds make up a single minute",
"FSC.Configuration.Time.GameTimeRatio": "Game Seconds Per Real Life Seconds",
- "FSC.Configuration.Time.GameTimeRatioHelp": "How many seconds pass in game for every second that passes in real time.",
+ "FSC.Configuration.Time.GameTimeRatioHelp": "How many seconds pass in game for every second that passes in real time",
"FSC.Configuration.Time.Options": "Opciones de hora",
"FSC.Configuration.Time.ClockSettings": "Ajustes del reloj",
+ "FSC.Configuration.Time.UpdateFrequency": "Actualizar frecuencia",
+ "FSC.Configuration.Time.UpdateFrequencyHelp": "Esto determina como de a menudo se actualiza este reloj",
+ "FSC.Configuration.Time.UnifyGameAndClock": "Sincronizar el reloj con la pausa de juego",
+ "FSC.Configuration.Time.UnifyGameAndClockHelp": "Vincula los botones de inicio/parada del reloj con la pausa de juego",
"FSC.Configuration.Moon.Title": "Ajustes de la Luna",
"FSC.Configuration.Moon.Name": "Nombre de la Luna",
- "FSC.Configuration.Moon.NameHelp": "El nombre de esta luna.",
+ "FSC.Configuration.Moon.NameHelp": "El nombre de esta luna",
"FSC.Configuration.Moon.CycleLength": "Longitud del ciclo",
- "FSC.Configuration.Moon.CycleLengthHelp": "La duración del ciclo lunar en días. Acepta decimales.",
+ "FSC.Configuration.Moon.CycleLengthHelp": "La duración del ciclo lunar en días. Acepta decimales",
"FSC.Configuration.Moon.CycleAdjustment": "Ajuste del ciclo",
- "FSC.Configuration.Moon.CycleAdjustmentHelp": "La cantidad de días para ajustar el cálculo por cuando se determina la fase actual.",
+ "FSC.Configuration.Moon.CycleAdjustmentHelp": "La cantidad de días para ajustar el cálculo por cuando se determina la fase actual",
"FSC.Configuration.Moon.Color": "Color de la Luna",
- "FSC.Configuration.Moon.ColorHelp": "El color que se asocia a esta luna.",
+ "FSC.Configuration.Moon.ColorHelp": "El color que se asocia a esta luna",
"FSC.Configuration.Moon.Add": "Añadir Luna Nueva",
"FSC.Configuration.Moon.RemoveAll": "Eliminar todas las lunas",
"FSC.Configuration.Moon.Phases": "Fases",
"FSC.Configuration.Moon.PhaseName": "Nombre de Fase",
- "FSC.Configuration.Moon.PhaseNameHelp": "El nombre de esta fase de la Luna.",
+ "FSC.Configuration.Moon.PhaseNameHelp": "El nombre de esta fase de la Luna",
"FSC.Configuration.Moon.PhaseLength": "Longitud de la Fase",
- "FSC.Configuration.Moon.PhaseLengthHelp": "Cuánto tiempo dura la fase en días.",
+ "FSC.Configuration.Moon.PhaseLengthHelp": "Cuánto tiempo dura la fase en días",
"FSC.Configuration.Moon.PhaseSingleDay": "Fase de un día",
- "FSC.Configuration.Moon.PhaseSingleDayHelp": "Si esta fase lunar debe ocurrir sólo en un día.",
+ "FSC.Configuration.Moon.PhaseSingleDayHelp": "Si esta fase lunar debe ocurrir sólo en un día",
"FSC.Configuration.Moon.PhaseIcon": "Icono de Fase",
- "FSC.Configuration.Moon.PhaseIconHelp": "El icono para asociar con esta fase lunar.",
+ "FSC.Configuration.Moon.PhaseIconHelp": "El icono para asociar con esta fase lunar",
"FSC.Configuration.Moon.PhaseAdd": "Añadir fase lunar nueva",
"FSC.Configuration.Moon.PhaseRemoveAll": "Eliminar todas las fases lunares",
"FSC.Configuration.Moon.FirstNewMoon": "Referencia de Luna Nueva",
"FSC.Configuration.Moon.YearReset": "Reinciar la referencia del año lunar",
- "FSC.Configuration.Moon.YearResetHelp": "Si el año para la luna de referencia debe resetearse y en caso afirmativo, cuando lo haga.",
+ "FSC.Configuration.Moon.YearResetHelp": "Si el año para la luna de referencia debe resetearse y en caso afirmativo, cuando lo haga",
"FSC.Configuration.Moon.YearResetNo": "No restablecer año de referencia",
"FSC.Configuration.Moon.YearResetLeap": "Restablecer año de referencia cada año bisiesto",
"FSC.Configuration.Moon.YearResetX": "Restablecer año de referencia cada X años",
"FSC.Configuration.Moon.YearX": "Restablecer los años de referencia lunar",
- "FSC.Configuration.Moon.YearXHelp": "Restablecer el año de referencia lunas nuevas cada x número de años.",
+ "FSC.Configuration.Moon.YearXHelp": "Restablecer el año de referencia lunas nuevas cada x número de años",
"FSC.Configuration.Moon.Year": "Nuevo año lunar",
- "FSC.Configuration.Moon.YearHelp": "El año de una luna nueva a utilizar como referencia.",
+ "FSC.Configuration.Moon.YearHelp": "El año de una luna nueva a utilizar como referencia",
"FSC.Configuration.Moon.Month": "Mes Lunar Nuevo",
- "FSC.Configuration.Moon.MonthHelp": "El mes de una luna nueva para usar como referencia.",
+ "FSC.Configuration.Moon.MonthHelp": "El mes de una luna nueva para usar como referencia",
"FSC.Configuration.Moon.Day": "Día de la Luna Nueva",
- "FSC.Configuration.Moon.DayHelp": "El día de una luna nueva para usar como referencia.",
+ "FSC.Configuration.Moon.DayHelp": "El día de una luna nueva para usar como referencia",
"FSC.Configuration.Moons": "Lunas",
- "FSC.Warn.Time.ActiveCombats": "Se está ejecutando un combate/combate activo, por favor resuelve antes de iniciar el reloj en tiempo real.",
- "FSC.Warn.Notes.NotGM": "No hay ningún GM presente en el juego, un GM necesita estar conectado para que los jugadores añadan notas.",
+ "FSC.Warn.Time.ActiveCombats": "Se está ejecutando un combate/combate activo, por favor resuelve antes de iniciar el reloj en tiempo real",
+ "FSC.Warn.Notes.NotGM": "No hay ningún GM presente en el juego, un GM necesita estar conectado para que los jugadores añadan notas",
"FSC.Warn.Macros.GMUpdate": "¡Sólo el GM puede actualizar la fecha del calendario!",
- "FSC.Warn.Calendar.NotGM": "No hay ningún GM presente en el juego, es necesario iniciar sesión en un GM para que los jugadores cambien la fecha/hora.",
+ "FSC.Warn.Calendar.NotGM": "No hay ningún GM presente en el juego, es necesario iniciar sesión en un GM para que los jugadores cambien la fecha/hora",
"FSC.Error.Note.NoTitle": "¡No se puede guardar una nota sin título!",
- "FSC.Error.Note.RichText": "Por favor, guarda el contenido del editor enriquecido.",
- "FSC.Error.Note.NoSelectedDay": "No se puede agregar una nueva nota, no hay ningún día seleccionado.",
- "FSC.Error.Note.NoSelectedMonth": "No se puede agregar una nueva nota, no hay ningún mes seleccionado.",
- "FSC.Error.Calendar.GMConfigure": "Necesitas ser un GM para configurar el calendario.",
- "FSC.Error.Calendar.GMCurrent": "Debe ser un GM para cambiar la fecha actual.",
+ "FSC.Error.Note.RichText": "Por favor, guarda el contenido del editor enriquecido",
+ "FSC.Error.Note.NoSelectedDay": "No se puede agregar una nueva nota, no hay ningún día seleccionado",
+ "FSC.Error.Note.NoSelectedMonth": "No se puede agregar una nueva nota, no hay ningún mes seleccionado",
+ "FSC.Error.Calendar.GMConfigure": "Necesitas ser un GM para configurar el calendario",
+ "FSC.Error.Calendar.GMCurrent": "Debe ser un GM para cambiar la fecha actual",
"FSC.Module.Import": "Importar en el Simple Calendar",
"FSC.Module.NoChanges": "Sin cambios",
"FSC.Module.CalendarWeather.Title": "¡Módulo de Calendario/Tiempo detectado!",
@@ -273,5 +311,7 @@
"FSC.Module.AboutTime.Title": "Acerca de Módulo de Tiempo detectado",
"FSC.Module.AboutTime.Message": "Hemos detectado que el módulo about-time está/ha sido activado para este mundo.
Si desea importar la configuración del calendario about-time en el calendario simple seleccione \"Importar en el calendario simple\", esto hará que el Calendario Simple coincida con los ajustes de about-time.
Si desea que coincida con Simple Calendar elija \"Exportar en Acerca de tiempo\", esto hará que los ajustes de about-time coincidan con la configuración Simple Calendars .
De lo contrario, puede elegir \"Sin Cambios\" y las cosas se dejarán como están. Si desea realizar una importación/exportación más adelante, la opción estará disponible en la configuración general de Simple Calendar. ",
"FSC.Module.AboutTime.Configuration.Message": "Hemos detectado que el módulo about-time está/ha sido habilitado para este mundo.
Si desea importar la configuración del calendario about-time en el calendario simple elija \"Importar en el calendario simple\", esto hará que el Calendario Simple coincida con la configuración de about-time.
Si desea que coincida con Simple Calendar seleccione \"Exportar en Acerca de tiempo\", esto hará que los ajustes de about-time coincidan con la configuración de Simple Calendars . ",
- "FSC.Module.AboutTime.Export": "Exportar en Acerca del Tiempo"
+ "FSC.Module.AboutTime.Export": "Exportar en Acerca del Tiempo",
+ "FSC.Importer.NoFile": "Por favor, seleccione un fichero a importar",
+ "FSC.Importer.InvalidSCConfig": "Fichero subido no válido, por favor, seleccione un fichero JSON de exportación de Simple Calendar"
}
\ No newline at end of file
diff --git a/src/lang/fr.json b/src/lang/fr.json
new file mode 100644
index 00000000..7ad31dd5
--- /dev/null
+++ b/src/lang/fr.json
@@ -0,0 +1,314 @@
+{
+ "FSC.Title": "Simple Calendar",
+ "FSC.Compact": "Compact",
+ "FSC.Full": "Complet",
+ "FSC.Help": "Aide",
+ "FSC.One": "1",
+ "FSC.Five": "5",
+ "FSC.Thirty": "30",
+ "FSC.OrdinalSuffix.st": "er",
+ "FSC.OrdinalSuffix.nd": "e",
+ "FSC.OrdinalSuffix.rd": "e",
+ "FSC.OrdinalSuffix.th": "e",
+ "FSC.ButtonTitle": "Calendrier",
+ "FSC.AllDay": "Toute la journée",
+ "FSC.Day": "Jour",
+ "FSC.Days": "Jours",
+ "FSC.Month": "Mois",
+ "FSC.Year": "Année",
+ "FSC.Hour": "Heure",
+ "FSC.HourShorthand": "hr",
+ "FSC.Minute": "Minute",
+ "FSC.MinuteShorthand": "min",
+ "FSC.Second": "Seconde",
+ "FSC.SecondShorthand": "sec",
+ "FSC.Forward": "Avancer",
+ "FSC.Back": "Reculer",
+ "FSC.Clear": "Effacer",
+ "FSC.Random": "Aléatoire",
+ "FSC.ShowAdvanced": "Afficher Avancé",
+ "FSC.HideAdvanced": "Masquer Avancé",
+ "FSC.DateControls": "Contrôles de date",
+ "FSC.DateControlsHelp": "Utilisez ces commandes pour modifier la date actuelle dans votre jeu.",
+ "FSC.NoDateControls": "Simple Calendar a été configuré pour laisser un autre module contrôler la date et l'heure. Veuillez utiliser ce module pour mettre à jour l'heure ou modifier la configuration de Simple Calendars.",
+ "FSC.SetCurrentDate": "Définir la date actuelle",
+ "FSC.SetCurrentDateDialog.Title": "Confirmer le changement de date actuelle",
+ "FSC.SetCurrentDateDialog.Content": "Vous avez choisi de changer la date en un jour qui n'est actuellement pas visible ! Voulez-vous vraiment changer la date du jour en {DATE} ?",
+ "FSC.Apply": "Appliquer",
+ "FSC.AdvancedOptions": "Options Avancées",
+ "FSC.Today": "Ajourd'hui",
+ "FSC.Configure": "Configurer",
+ "FSC.Import": "Importer",
+ "FSC.Export": "Exporter",
+ "FSC.By": "Par",
+ "FSC.Cancel": "Annuler",
+ "FSC.Edit": "Éditer",
+ "FSC.Delete": "Supprimer",
+ "FSC.DeleteConfirm": "Confirmer la suppression",
+ "FSC.DeleteConfirmText": "Vous voulez vraiment supprimer cette note?",
+ "FSC.OverwriteConfirm": "Écraser",
+ "FSC.OverwriteConfirmText": "L'application de cette modification écrasera toutes les configurations de calendrier existantes. Êtes-vous sûr?",
+ "FSC.ChangeNextMonth": "Passer au mois suivant",
+ "FSC.ChangePreviousMonth": "Passer au mois précédent",
+ "FSC.MoveYearForward": "Avancer d'un an",
+ "FSC.MoveMonthForward": "Avancer d'un mois",
+ "FSC.MoveDayForward": "Avancer d'un jour",
+ "FSC.MoveYearBack": "Reculer d'un an",
+ "FSC.MoveMonthBack": "Reculer d'un mois",
+ "FSC.MoveDayBack": "Retour d'un jour",
+ "FSC.Time.Controls": "Contrôles de temps",
+ "FSC.Time.ControlsHelp": "Sélectionnez une unité de temps à modifier puis utilisez les commandes pour augmenter ou réduire cette unité de 1 ou 5",
+ "FSC.Time.Forward": "Avancer le temps.",
+ "FSC.Time.Backward": "Reculer le temps.",
+ "FSC.Time.Start": "Commencer à avancer le temps de jeu",
+ "FSC.Time.Stop": "Arrêter d'avancer le temps de jeu",
+ "FSC.Notes.DialogTitle": "Note",
+ "FSC.Notes.New": "Nouvelle note",
+ "FSC.Notes.Empty": "Aucune note pour cette date",
+ "FSC.Notes.For": "Notes pour",
+ "FSC.Notes.AddNew": "Ajouter une nouvelle note",
+ "FSC.Notes.NewFor": "Nouvelle note pour",
+ "FSC.Notes.Title": "Titre de la note",
+ "FSC.Notes.TitleHelp": "Le titre de cette note.",
+ "FSC.Notes.Date": "Date de la note",
+ "FSC.Notes.DateHelp": "La date de la note.",
+ "FSC.Notes.NotPlayerVisible": "Non visible aux Joueurs",
+ "FSC.Notes.PlayerVisible": "Visible aux Joueurs",
+ "FSC.Notes.PlayerVisibleHelp": "Si cette note est visible par les joueurs ou non.",
+ "FSC.Notes.Reminder": "Rappelez-moi!",
+ "FSC.Notes.ReminderHelp": "Cet événement vous sera rappelé.",
+ "FSC.Notes.Repeating": "Récurrence de la note",
+ "FSC.Notes.RepeatingHelp": "Si cette note se répète hebdomadairement, mensuellement, annuellement ou pas du tout.",
+ "FSC.Notes.Save": "Enregistrer la note",
+ "FSC.Notes.Repeats": "Récurrence",
+ "FSC.Notes.Repeat.Never": "Jamais",
+ "FSC.Notes.Repeat.Monthly": "Mensuel",
+ "FSC.Notes.Repeat.Yearly": "Annuel",
+ "FSC.Notes.Repeat.Weekly": "Hebdomadaire",
+ "FSC.Notes.Time": "Temps",
+ "FSC.Notes.DateTime.Title": "Note Date/Heure",
+ "FSC.Notes.DateTime.Help": "La date de la note et éventuellement l'heure à laquelle la note se produit.",
+ "FSC.Notes.DateTime.AllDay": "Ajouter une heure",
+ "FSC.Notes.Author": "Auteur",
+ "FSC.Date.Sunday": "Dimanche",
+ "FSC.Date.Monday": "Lundi",
+ "FSC.Date.Tuesday": "Mardi",
+ "FSC.Date.Wednesday": "Mercredi",
+ "FSC.Date.Thursday": "Jeudi",
+ "FSC.Date.Friday": "Vendredi",
+ "FSC.Date.Saturday": "Samedi",
+ "FSC.Date.January": "Janvier",
+ "FSC.Date.February": "Février",
+ "FSC.Date.March": "Mars",
+ "FSC.Date.April": "Avril",
+ "FSC.Date.May": "Mai",
+ "FSC.Date.June": "Juin",
+ "FSC.Date.July": "Juillet",
+ "FSC.Date.August": "Août",
+ "FSC.Date.September": "Septembre",
+ "FSC.Date.October": "Octobre",
+ "FSC.Date.November": "Novembre",
+ "FSC.Date.December": "Décembre",
+ "FSC.Time.Current": "Heure actuelle",
+ "FSC.Moon.Phase.New": "Nouvelle Lune",
+ "FSC.Moon.Phase.WaxingCrescent": "Croissante",
+ "FSC.Moon.Phase.FirstQuarter": "Premier trimestre",
+ "FSC.Moon.Phase.WaxingGibbous": "Gibbeuse Croissante",
+ "FSC.Moon.Phase.Full": "Pleine Lune",
+ "FSC.Moon.Phase.WaningGibbous": "Gibbeuse Décroissante",
+ "FSC.Moon.Phase.LastQuarter": "Dernier trimestre",
+ "FSC.Moon.Phase.WaningCrescent": "Décroissante",
+ "FSC.Configuration.Title": "Configuration du calendrier",
+ "FSC.Configuration.Description": "Ce formulaire vous permet de personnaliser votre calendrier de jeux en précisant l'année en cours, le nombre de mois, le nom de chaque mois et le nombre de jours de chaque mois.",
+ "FSC.Configuration.Help": "Pour obtenir de l'aide sur la configuration du calendrier, assurez-vous de consulter la documentation!",
+ "FSC.Configuration.Save": "Enregistrer la configuration",
+ "FSC.Configuration.General.Title": "Paramètres généraux",
+ "FSC.Configuration.General.PreDefined": "Calendriers prédéfinis",
+ "FSC.Configuration.General.PreDefinedHelp": "Choisissez l'un des calendriers prédéfinis pour démarrer la configuration plus rapidement.",
+ "FSC.Configuration.General.GameWorldTime": "Intégration du temps dans le monde du jeu",
+ "FSC.Configuration.General.GameWorldTimeHelp": "Dites à Simple Calendar comment s'intégrer au temps du monde de jeu et répondre aux mises à jour du temps du monde de jeu.",
+ "FSC.Configuration.General.None": "Aucun : N'est pas lié au temps du monde de jeu.",
+ "FSC.Configuration.General.Self": "Local: Contrôlez le temps du monde de jeu en ignorant les mises à jour des autres modules.",
+ "FSC.Configuration.General.ThirdParty": "Module tiers : Suit uniquement les mises à jour du temps du monde de jeu provenant d'autres modules.",
+ "FSC.Configuration.General.Mixed": "Hybride : Mettre à jour le temps du monde de jeu et suivre les mises à jour effectuées à partir d'autres modules.",
+ "FSC.Configuration.General.PF2ESync": "Pathfinder 2E : synchronisation du temps du monde de jeu",
+ "FSC.Configuration.General.PF2ESyncHelp": "Cela forcera Simple Calendar à rester synchronisé avec le temps du monde de jeu intégrée de Pathfinder 2E.",
+ "FSC.Configuration.General.ShowClock": "Afficher l'horloge",
+ "FSC.Configuration.General.ShowClockHelp": "Pour afficher l'horloge sous le calendrier, si coché. Les commandes pour changer les heures, les minutes et les secondes s'afficheront également.",
+ "FSC.Configuration.General.PlayerAddNotes": "Ajouter des notes",
+ "FSC.Configuration.General.PlayerAddNotesHelp": "Les rôles sélectionnés pourront ajouter des notes au calendrier.",
+ "FSC.Configuration.General.PlayerReorderNotes": "Réorganiser les notes",
+ "FSC.Configuration.General.PlayerReorderNotesHelp": "Les rôles sélectionnés pourront réorganiser les notes d'une journée.",
+ "FSC.Configuration.General.QuickSetup": "Configuration rapide",
+ "FSC.Configuration.General.Notes": "Notes",
+ "FSC.Configuration.General.ImportExport.Title": "Importer/Exporter",
+ "FSC.Configuration.General.ImportExport.SCConfig": "Importer/Exporter la configuration du calendrier",
+ "FSC.Configuration.General.ImportExport.SCConfigHelp": "Pour importer ou exporter la configuration actuelle de Simple Calendar pour partager ou charger la réplication dans un autre monde.",
+ "FSC.Configuration.General.ThirdPartyModule": "Importation/Exportation de modules tiers",
+ "FSC.Configuration.General.Permissions.Note": "Ici, les autorisations pour diverses interactions avec Simple Calendar peuvent être ajustées en fonction des rôles de Foundry. Les maîtres de jeu auront toujours ces autorisations.",
+ "FSC.Configuration.General.CalendarPlayerVisible": "Afficher le calendrier",
+ "FSC.Configuration.General.CalendarPlayerVisibleHelp": "Les rôles cochés pourront ouvrir Simple Calendar.",
+ "FSC.Configuration.General.PlayersChangeDateTime": "Modifier la date et l'heure",
+ "FSC.Configuration.General.PlayersChangeDateTimeHelp": "Les rôles cochés pourront changer la date et l'heure de Simple Calendar",
+ "FSC.Configuration.Notes.Title": "Paramètres des notes",
+ "FSC.Configuration.Notes.NoteCategories": "Catégories de notes",
+ "FSC.Configuration.NoteCategories.Name": "Nom de la catégorie de note",
+ "FSC.Configuration.NoteCategories.NameHelp": "Le nom d'affichage de cette catégorie de note.",
+ "FSC.Configuration.NoteCategories.Color": "Couleur de la catégorie de note",
+ "FSC.Configuration.NoteCategories.ColorHelp": "La couleur associée à la catégorie de note.",
+ "FSC.Configuration.NoteCategories.Add": "Ajouter une catégorie de note",
+ "FSC.Configuration.NoteCategories.RemoveAll": "Supprimer toutes les catégories de notes",
+ "FSC.Configuration.Notes.NoteCategoriesHelp": "Sélectionnez toutes les différentes catégories de notes associées à cette note.",
+ "FSC.Configuration.Year.Title": "Paramètres de l'année",
+ "FSC.Configuration.Year.Current": "Année Courante",
+ "FSC.Configuration.Year.CurrentHelp": "L'année en cours pendant laquelle le jeu se déroule. Cela peut également être modifié avec les contrôles de date.",
+ "FSC.Configuration.Year.Prefix": "Année Préfixe",
+ "FSC.Configuration.Year.PrefixHelp": "Texte qui apparaît avant le numéro de l'année.",
+ "FSC.Configuration.Year.Postfix": "Année Suffix",
+ "FSC.Configuration.Year.PostfixHelp": "Texte qui apparaît après le numéro de l'année.",
+ "FSC.Configuration.Year.YearZero": "Année zéro",
+ "FSC.Configuration.Year.YearZeroHelp": "C'est l'année qui est considérée comme l'année zéro pour calculer combien de temps s'est écoulé. Cela n'a généralement pas besoin d'être modifié.",
+ "FSC.Configuration.Year.YearNames": "Noms des années",
+ "FSC.Configuration.Year.YearName": "Nom de l'année",
+ "FSC.Configuration.Year.YearNameAdd": "Ajouter le nom du nouvel an",
+ "FSC.Configuration.Year.YearNameRemove": "Supprimer tous les noms d'année",
+ "FSC.Configuration.Year.YearNamesStart": "Année de début pour les noms",
+ "FSC.Configuration.Year.YearNamesStartHelp": "L'année de début du premier nom de l'année sur la liste.",
+ "FSC.Configuration.Year.YearNameBehaviour": "Comportement des noms d'années",
+ "FSC.Configuration.Year.YearNameBehaviourHelp": "Comment déterminer l'ordre des noms d'année.",
+ "FSC.Configuration.Year.Seasons": "Saisons",
+ "FSC.Configuration.Season.Name": "Nom de la saison",
+ "FSC.Configuration.Season.NameHelp": "Le nom de cette saison.",
+ "FSC.Configuration.Season.StartingMonth": "Mois de début",
+ "FSC.Configuration.Season.StartingMonthHelp": "Le mois où cette saison commence chaque année.",
+ "FSC.Configuration.Season.StartingDay": "Jour de début",
+ "FSC.Configuration.Season.StartingDayHelp": "Le jour du mois où cette saison commence chaque année.",
+ "FSC.Configuration.Season.Color": "Couleur",
+ "FSC.Configuration.Season.ColorHelp": "La couleur à associer à cette saison.",
+ "FSC.Configuration.Season.ColorWhite": "Blanc",
+ "FSC.Configuration.Season.ColorSpring": "Printemps",
+ "FSC.Configuration.Season.ColorSummer": "Été",
+ "FSC.Configuration.Season.ColorFall": "Automne",
+ "FSC.Configuration.Season.ColorWinter": "Hiver",
+ "FSC.Configuration.Season.ColorCustom": "Couleur personnalisée",
+ "FSC.Configuration.Season.ColorCustomHelp": "Définir une couleur de valeur hexadécimale personnalisée pour la saison.",
+ "FSC.Configuration.Season.RemoveAll": "Supprimer toutes les saisons",
+ "FSC.Configuration.Season.Add": "Ajouter une nouvelle saison",
+ "FSC.Configuration.Month.Title": "Paramètres du mois",
+ "FSC.Configuration.Month.Name": "Nom du mois",
+ "FSC.Configuration.Month.NameHelp": "Le nom textuel de ce mois.",
+ "FSC.Configuration.Month.Days": "Nombre de jours",
+ "FSC.Configuration.Month.DaysHelp": "Le nombre de jours qui composent ce mois.",
+ "FSC.Configuration.Month.Intercalaire": "Mois Intercalaire",
+ "FSC.Configuration.Month.IntercalaryHelp": "Si ce mois doit être considéré comme un mois intercalaire ou non.",
+ "FSC.Configuration.Month.IntercalaryInclude": "Inclure le mois intercalaire dans les calculs de jour",
+ "FSC.Configuration.Month.IntercalaryIncludeHelp": "Si coché, le mois intercalaire sera traité comme un mois normal pour calculer le jour de la semaine et le nombre total de jours dans une année, mais sera toujours répertorié comme un mois intercalaire.",
+ "FSC.Configuration.Month.DayOffset": "Décalage du jour",
+ "FSC.Configuration.Month.DayOffsetHelp": "Le montant pour décaler le numéro du jour. Utilisé si vous voulez commencer un mois à 2 au lieu de 1",
+ "FSC.Configuration.Month.Number": "Numéro de mois",
+ "FSC.Configuration.Month.NumberHelp": "La représentation numérique de ce mois.",
+ "FSC.Configuration.Month.StartingWeekDay": "Démarre le jour de la semaine",
+ "FSC.Configuration.Month.StartingWeekDayHelp": "Choisissez par quel jour de la semaine ce mois commencera toujours, ou laissez par défaut pour laisser le calendrier déterminer le jour de la semaine approprié.",
+ "FSC.Configuration.Month.Remove": "Supprimer",
+ "FSC.Configuration.Month.RemoveAll": "Supprimer tous les mois",
+ "FSC.Configuration.Month.Add": "Ajouter un nouveau mois",
+ "FSC.Configuration.Months": "Mois",
+ "FSC.Configuration.Weekday.Title": "Paramètres des jours de la semaine",
+ "FSC.Configuration.Weekday.ShowHeadings": "Afficher les titres des jours de la semaine",
+ "FSC.Configuration.Weekday.ShowHeadingsHelp": "Cochez pour afficher.",
+ "FSC.Configuration.Weekday.Name": "Nom du jour de la semaine",
+ "FSC.Configuration.Weekday.NameHelp": "Le nom textuel de ce jour de la semaine.",
+ "FSC.Configuration.Weekday.Add": "Ajouter un nouveau jour de la semaine",
+ "FSC.Configuration.Weekday.RemoveAll": "Supprimer tous les jours de la semaine",
+ "FSC.Configuration.Weekdays": "Jours de la semaine",
+ "FSC.Configuration.Weekday.Options": "Options des jours de la semaine",
+ "FSC.Configuration.Weekday.FirstWeekDay": "Premier jour de la semaine",
+ "FSC.Configuration.Weekday.FirstWeekDayHelp": "Ceci définit le jour de la semaine où commence le premier jour de l'année 0.",
+ "FSC.Configuration.DefaultNoteVisibility": "Notez la visibilité par défaut du lecteur",
+ "FSC.Configuration.DefaultNoteVisibilityHint": "Pour les nouvelles notes, la visibilité par défaut pour les Joueurs",
+ "FSC.Configuration.LeapYear.Title": "Paramètres des années bissextiles",
+ "FSC.Configuration.LeapYear.Rule": "Règles des années bissextiles",
+ "FSC.Configuration.LeapYear.RuleHelp": "Les règles à suivre pour déterminer les années bissextiles.",
+ "FSC.Configuration.LeapYear.CustomMod": "Quand les années bissextiles arrivent",
+ "FSC.Configuration.LeapYear.CustomModHelp": "Chaque x nombre d'années est une année bissextile.",
+ "FSC.Configuration.LeapYear.Rules.None": "Aucun",
+ "FSC.Configuration.LeapYear.Rules.Gregorian": "Grégorien",
+ "FSC.Configuration.LeapYear.Rules.Custom": "Personnalisé",
+ "FSC.Configuration.LeapYear.Days": "Nombre de jours dans une année bissextile",
+ "FSC.Configuration.LeapYear.DaysHelp": "Le nombre de jours qui composent ce mois au cours d'une année bissextile.",
+ "FSC.Configuration.LeapYear.Options": "Options des années bissextiles",
+ "FSC.Configuration.Time.Title": "Paramètres de temps",
+ "FSC.Configuration.Time.HoursInDay": "Heures dans une journée",
+ "FSC.Configuration.Time.HoursInDayHelp": "Combien d'heures composent une journée.",
+ "FSC.Configuration.Time.MinutesInHour": "Minutes dans une heure",
+ "FSC.Configuration.Time.MinutesInHourHelp": "Combien de minutes composent une heure.",
+ "FSC.Configuration.Time.SecondsInMinute": "Secondes dans une minute",
+ "FSC.Configuration.Time.SecondsInMinuteHelp": "Combien de secondes composent une minute.",
+ "FSC.Configuration.Time.GameTimeRatio": " Secondes de jeu par secondes de vie réelle ",
+ "FSC.Configuration.Time.GameTimeRatioHelp": "Combien de secondes s'écoulent dans le jeu pour chaque seconde qui passe en temps réel.",
+ "FSC.Configuration.Time.Options": "Options de temps",
+ "FSC.Configuration.Time.ClockSettings": "Paramètres de l'horloge",
+ "FSC.Configuration.Time.UpdateFrequency": "Fréquence de mise à jour",
+ "FSC.Configuration.Time.UpdateFrequencyHelp": "Ceci détermine la fréquence à laquelle l'horloge se met à jour.",
+ "FSC.Configuration.Time.UnifyGameAndClock": "Unifier le démarrage/pause de l'horloge avec l'horloge du jeu",
+ "FSC.Configuration.Time.UnifyGameAndClockHelp": "Lie le bouton de démarrage/pause des horloges avec l'option de pause/reprise des jeux",
+ "FSC.Configuration.Moon.Title": "Paramètres de la lune",
+ "FSC.Configuration.Moon.Name": "Nom de la Lune",
+ "FSC.Configuration.Moon.NameHelp": "Le nom de cette lune.",
+ "FSC.Configuration.Moon.CycleLength": "Durée du cycle",
+ "FSC.Configuration.Moon.CycleLengthHelp": "La longueur du cycle lunaire en jours. Accepte les décimales.",
+ "FSC.Configuration.Moon.CycleAdjustment": "Réglage du cycle",
+ "FSC.Configuration.Moon.CycleAdjustmentHelp": "Le nombre de jours pour ajuster le calcul lors de la détermination de la phase actuelle.",
+ "FSC.Configuration.Moon.Color": "Couleur de la lune",
+ "FSC.Configuration.Moon.ColorHelp": "La couleur à associer à cette lune.",
+ "FSC.Configuration.Moon.Add": "Ajouter une nouvelle lune",
+ "FSC.Configuration.Moon.RemoveAll": "Supprimer toutes les lunes",
+ "FSC.Configuration.Moon.Phases": "Phases",
+ "FSC.Configuration.Moon.PhaseName": "Nom de phase",
+ "FSC.Configuration.Moon.PhaseNameHelp": "Le nom de cette phase de la lune.",
+ "FSC.Configuration.Moon.PhaseLength": "Longueur de phase",
+ "FSC.Configuration.Moon.PhaseLengthHelp": "Combien de temps dure la phase en jours.",
+ "FSC.Configuration.Moon.PhaseSingleDay": "Phase d'une journée",
+ "FSC.Configuration.Moon.PhaseSingleDayHelp": "Si cette phase de lune ne doit se produire que sur 1 jour.",
+ "FSC.Configuration.Moon.PhaseIcon": "Icône de phase",
+ "FSC.Configuration.Moon.PhaseIconHelp": "L'icône à associer à cette phase de lune.",
+ "FSC.Configuration.Moon.PhaseAdd": "Ajouter une nouvelle phase de lune",
+ "FSC.Configuration.Moon.PhaseRemoveAll": "Supprimer toutes les phases de la lune",
+ "FSC.Configuration.Moon.FirstNewMoon": "Référence Nouvelle Lune",
+ "FSC.Configuration.Moon.YearReset": "Réinitialiser l'année de la lune de référence",
+ "FSC.Configuration.Moon.YearResetHelp": "Si l'année de la lune de référence doit être réinitialisée et si c'est le cas quand.",
+ "FSC.Configuration.Moon.YearResetNo": "Ne pas réinitialiser l'année de référence",
+ "FSC.Configuration.Moon.YearResetLeap": "Réinitialiser l'année de référence chaque année bissextile",
+ "FSC.Configuration.Moon.YearResetX": "Réinitialiser l'année de référence tous les X ans",
+ "FSC.Configuration.Moon.YearX": "Réinitialiser les années lunaires de référence",
+ "FSC.Configuration.Moon.YearXHelp": "Réinitialiser l'année de référence des nouvelles lunes tous les x nombre d'années.",
+ "FSC.Configuration.Moon.Year": "Année de la Nouvelle Lune",
+ "FSC.Configuration.Moon.YearHelp": "L'année d'une nouvelle lune à utiliser comme référence.",
+ "FSC.Configuration.Moon.Month": "Mois de la Nouvelle Lune",
+ "FSC.Configuration.Moon.MonthHelp": "Le mois d'une nouvelle lune à utiliser comme référence.",
+ "FSC.Configuration.Moon.Day": "Jour de la Nouvelle Lune",
+ "FSC.Configuration.Moon.DayHelp": "Le jour d'une nouvelle lune à utiliser comme référence.",
+ "FSC.Configuration.Moons": "Lunes",
+ "FSC.Warn.Time.ActiveCombats": "Il y a un ou des combats actifs en cours, veuillez les résoudre avant de démarrer l'horloge en temps réel.",
+ "FSC.Warn.Notes.NotGM": "Il n'y a pas de Maître de Jeu présent dans le jeu, un Maître de Jeu doit être connecté pour que les joueurs puissent ajouter des notes.",
+ "FSC.Warn.Macros.GMUpdate": "Seul le Maître de Jeu peut mettre à jour la date du calendrier!",
+ "FSC.Warn.Calendar.NotGM": "Il n'y a pas de Maître de Jeu présent dans le jeu, un Maître de Jeu doit être connecté pour que les joueurs puissent changer la date/l'heure.",
+ "FSC.Error.Note.NoTitle": "Impossible d'enregistrer une note sans titre !",
+ "FSC.Error.Note.RichText": "Veuillez enregistrer le contenu de l'éditeur enrichi.",
+ "FSC.Error.Note.NoSelectedDay": "Impossible d'ajouter une nouvelle note, il n'y a pas de jour sélectionné.",
+ "FSC.Error.Note.NoSelectedMonth": "Impossible d'ajouter une nouvelle note, il n'y a pas de mois sélectionné.",
+ "FSC.Error.Calendar.GMConfigure": "Vous devez être Maître de Jeu pour configurer le calendrier.",
+ "FSC.Error.Calendar.GMCurrent": "Vous devez être Maître de Jeu pour changer la date actuelle.",
+ "FSC.Module.Import": "Importer dans Simple Calendar",
+ "FSC.Module.NoChanges": "Aucun changement",
+ "FSC.Module.CalendarWeather.Title": "Module Calendar/Weather détecté !",
+ "FSC.Module.CalendarWeather.Message": "Nous avons détecté que le module Calendar/Weather est activé pour ce monde.
Si vous souhaitez importer les paramètres de Calendar/Weather vers Simple Calendar, choisissez \"Importer vers Simple Calendar\", cela fera correspondre le Simple Calendar aux paramètres de Calendar/Weather.
Si vous souhaitez que Calendar/Weather corresponde a Simple Calendar, choisissez \"Exporter vers Calendar/Weather \", cela fera correspondre les paramètres de Calendar/Weather à la configuration de Simple Calendar.
Sinon, vous pouvez choisir \"Aucun changement\" et les choses resteront telles quelles. Si vous souhaitez importer/exporter plus tard, l'option sera disponible dans les paramètres généraux de Simple Calendar. ",
+ "FSC.Module.CalendarWeather.Configuration.Message": "Nous avons détecté que le module Calendar/Weather est activé pour ce monde.
Si vous souhaitez importer les paramètres de Calendar/Weather vers Simple Calendar, choisissez \"Importer vers Simple Calendar\", cela fera correspondre Simple Calendar aux paramètres de Calendar/Weather.
Si vous souhaitez que Calendar/Weather corresponde à Simple Calendar, choisissez \"Exporter vers Calendar/Weather\", cela fera correspondre les paramètres de Calendar/Weather à la configuration de Simple Calendar. ",
+ "FSC.Module.CalendarWeather.Export": "Exporter vers Calendar/Weather",
+ "FSC.Module.AboutTime.Title": "Module About-Time détecté",
+ "FSC.Module.AboutTime.Message": "Nous avons détecté que le module About-Time est/a été activé pour ce monde.
Si vous souhaitez importer les paramètres de About-Time vers Simple Calendar, choisissez \"Importer vers Simple Calendar\", cela fera correspondre Simple Calendar aux paramètres de About-Time.
Si vous souhaitez faire correspondre Simple Calendar, choisissez \"Exporter vers About-Time\", cela fera correspondre les paramètres de About-Time à la configuration de Simple Calendar.
Sinon, vous pouvez choisir \"Aucune modification\" et les choses resteront telles quelles. Si vous le souhaitez importer/exporter plus tard, l'option sera disponible dans les paramètres généraux de Simple Calendar. ",
+ "FSC.Module.AboutTime.Configuration.Message": "Nous avons détecté que le module About-Time est/a été activé pour ce monde.
Si vous souhaitez importer le calendrier de About-Time vers Simple Calendar, choisissez \"Importer vers Simple Calendar\", cela fera correspondre Simple Calendar aux paramètres de About-Time.