Subversion Repositories Applications.papyrus

Rev

Rev 1372 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1318 alexandre_ 1
/*
2
	Copyright (c) 2004-2006, The Dojo Foundation
3
	All Rights Reserved.
4
 
5
	Licensed under the Academic Free License version 2.1 or above OR the
6
	modified BSD license. For more information on Dojo licensing, see:
7
 
8
		http://dojotoolkit.org/community/licensing.shtml
9
*/
10
 
1422 alexandre_ 11
 
12
 
1318 alexandre_ 13
dojo.provide("dojo.cal.iCalendar");
14
dojo.require("dojo.lang.common");
15
dojo.require("dojo.cal.textDirectory");
16
dojo.require("dojo.date.common");
17
dojo.require("dojo.date.serialize");
18
dojo.cal.iCalendar.fromText = function (text) {
19
	var properties = dojo.cal.textDirectory.tokenise(text);
20
	var calendars = [];
21
	for (var i = 0, begun = false; i < properties.length; i++) {
22
		var prop = properties[i];
23
		if (!begun) {
24
			if (prop.name == "BEGIN" && prop.value == "VCALENDAR") {
25
				begun = true;
26
				var calbody = [];
27
			}
28
		} else {
29
			if (prop.name == "END" && prop.value == "VCALENDAR") {
30
				calendars.push(new dojo.cal.iCalendar.VCalendar(calbody));
31
				begun = false;
32
			} else {
33
				calbody.push(prop);
34
			}
35
		}
36
	}
37
	return calendars;
38
};
39
dojo.cal.iCalendar.Component = function (body) {
40
	if (!this.name) {
41
		this.name = "COMPONENT";
42
	}
43
	this.properties = [];
44
	this.components = [];
45
	if (body) {
46
		for (var i = 0, context = ""; i < body.length; i++) {
47
			if (context == "") {
48
				if (body[i].name == "BEGIN") {
49
					context = body[i].value;
50
					var childprops = [];
51
				} else {
52
					this.addProperty(new dojo.cal.iCalendar.Property(body[i]));
53
				}
54
			} else {
55
				if (body[i].name == "END" && body[i].value == context) {
56
					if (context == "VEVENT") {
57
						this.addComponent(new dojo.cal.iCalendar.VEvent(childprops));
58
					} else {
59
						if (context == "VTIMEZONE") {
60
							this.addComponent(new dojo.cal.iCalendar.VTimeZone(childprops));
61
						} else {
62
							if (context == "VTODO") {
63
								this.addComponent(new dojo.cal.iCalendar.VTodo(childprops));
64
							} else {
65
								if (context == "VJOURNAL") {
66
									this.addComponent(new dojo.cal.iCalendar.VJournal(childprops));
67
								} else {
68
									if (context == "VFREEBUSY") {
69
										this.addComponent(new dojo.cal.iCalendar.VFreeBusy(childprops));
70
									} else {
71
										if (context == "STANDARD") {
72
											this.addComponent(new dojo.cal.iCalendar.Standard(childprops));
73
										} else {
74
											if (context == "DAYLIGHT") {
75
												this.addComponent(new dojo.cal.iCalendar.Daylight(childprops));
76
											} else {
77
												if (context == "VALARM") {
78
													this.addComponent(new dojo.cal.iCalendar.VAlarm(childprops));
79
												} else {
80
													dojo.unimplemented("dojo.cal.iCalendar." + context);
81
												}
82
											}
83
										}
84
									}
85
								}
86
							}
87
						}
88
					}
89
					context = "";
90
				} else {
91
					childprops.push(body[i]);
92
				}
93
			}
94
		}
95
		if (this._ValidProperties) {
96
			this.postCreate();
97
		}
98
	}
99
};
100
dojo.extend(dojo.cal.iCalendar.Component, {addProperty:function (prop) {
101
	this.properties.push(prop);
102
	this[prop.name.toLowerCase()] = prop;
103
}, addComponent:function (prop) {
104
	this.components.push(prop);
105
}, postCreate:function () {
106
	for (var x = 0; x < this._ValidProperties.length; x++) {
107
		var evtProperty = this._ValidProperties[x];
108
		var found = false;
109
		for (var y = 0; y < this.properties.length; y++) {
110
			var prop = this.properties[y];
111
			var propName = prop.name.toLowerCase();
112
			if (dojo.lang.isArray(evtProperty)) {
113
				var alreadySet = false;
114
				for (var z = 0; z < evtProperty.length; z++) {
115
					var evtPropertyName = evtProperty[z].name.toLowerCase();
116
					if ((this[evtPropertyName]) && (evtPropertyName != propName)) {
117
						alreadySet = true;
118
					}
119
				}
120
				if (!alreadySet) {
121
					this[propName] = prop;
122
				}
123
			} else {
124
				if (propName == evtProperty.name.toLowerCase()) {
125
					found = true;
126
					if (evtProperty.occurance == 1) {
127
						this[propName] = prop;
128
					} else {
129
						found = true;
130
						if (!dojo.lang.isArray(this[propName])) {
131
							this[propName] = [];
132
						}
133
						this[propName].push(prop);
134
					}
135
				}
136
			}
137
		}
138
		if (evtProperty.required && !found) {
139
			dojo.debug("iCalendar - " + this.name + ": Required Property not found: " + evtProperty.name);
140
		}
141
	}
142
	if (dojo.lang.isArray(this.rrule)) {
143
		for (var x = 0; x < this.rrule.length; x++) {
144
			var rule = this.rrule[x].value;
145
			this.rrule[x].cache = function () {
146
			};
147
			var temp = rule.split(";");
148
			for (var y = 0; y < temp.length; y++) {
149
				var pair = temp[y].split("=");
150
				var key = pair[0].toLowerCase();
151
				var val = pair[1];
152
				if ((key == "freq") || (key == "interval") || (key == "until")) {
153
					this.rrule[x][key] = val;
154
				} else {
155
					var valArray = val.split(",");
156
					this.rrule[x][key] = valArray;
157
				}
158
			}
159
		}
160
		this.recurring = true;
161
	}
162
}, toString:function () {
163
	return "[iCalendar.Component; " + this.name + ", " + this.properties.length + " properties, " + this.components.length + " components]";
164
}});
165
dojo.cal.iCalendar.Property = function (prop) {
166
	this.name = prop.name;
167
	this.group = prop.group;
168
	this.params = prop.params;
169
	this.value = prop.value;
170
};
171
dojo.extend(dojo.cal.iCalendar.Property, {toString:function () {
172
	return "[iCalenday.Property; " + this.name + ": " + this.value + "]";
173
}});
174
var _P = function (n, oc, req) {
175
	return {name:n, required:(req) ? true : false, occurance:(oc == "*" || !oc) ? -1 : oc};
176
};
177
dojo.cal.iCalendar.VCalendar = function (calbody) {
178
	this.name = "VCALENDAR";
179
	this.recurring = [];
180
	this.nonRecurringEvents = function () {
181
	};
182
	dojo.cal.iCalendar.Component.call(this, calbody);
183
};
184
dojo.inherits(dojo.cal.iCalendar.VCalendar, dojo.cal.iCalendar.Component);
185
dojo.extend(dojo.cal.iCalendar.VCalendar, {addComponent:function (prop) {
186
	this.components.push(prop);
187
	if (prop.name.toLowerCase() == "vevent") {
188
		if (prop.rrule) {
189
			this.recurring.push(prop);
190
		} else {
191
			var startDate = prop.getDate();
192
			var month = startDate.getMonth() + 1;
193
			var dateString = month + "-" + startDate.getDate() + "-" + startDate.getFullYear();
194
			if (!dojo.lang.isArray(this[dateString])) {
195
				this.nonRecurringEvents[dateString] = [];
196
			}
197
			this.nonRecurringEvents[dateString].push(prop);
198
		}
199
	}
200
}, preComputeRecurringEvents:function (until) {
201
	var calculatedEvents = function () {
202
	};
203
	for (var x = 0; x < this.recurring.length; x++) {
204
		var dates = this.recurring[x].getDates(until);
205
		for (var y = 0; y < dates.length; y++) {
206
			var month = dates[y].getMonth() + 1;
207
			var dateStr = month + "-" + dates[y].getDate() + "-" + dates[y].getFullYear();
208
			if (!dojo.lang.isArray(calculatedEvents[dateStr])) {
209
				calculatedEvents[dateStr] = [];
210
			}
211
			if (!dojo.lang.inArray(calculatedEvents[dateStr], this.recurring[x])) {
212
				calculatedEvents[dateStr].push(this.recurring[x]);
213
			}
214
		}
215
	}
216
	this.recurringEvents = calculatedEvents;
217
}, getEvents:function (date) {
218
	var events = [];
219
	var recur = [];
220
	var nonRecur = [];
221
	var month = date.getMonth() + 1;
222
	var dateStr = month + "-" + date.getDate() + "-" + date.getFullYear();
223
	if (dojo.lang.isArray(this.nonRecurringEvents[dateStr])) {
224
		nonRecur = this.nonRecurringEvents[dateStr];
225
		dojo.debug("Number of nonRecurring Events: " + nonRecur.length);
226
	}
227
	if (dojo.lang.isArray(this.recurringEvents[dateStr])) {
228
		recur = this.recurringEvents[dateStr];
229
	}
230
	events = recur.concat(nonRecur);
231
	if (events.length > 0) {
232
		return events;
233
	}
234
	return null;
235
}});
236
var StandardProperties = [_P("dtstart", 1, true), _P("tzoffsetto", 1, true), _P("tzoffsetfrom", 1, true), _P("comment"), _P("rdate"), _P("rrule"), _P("tzname")];
237
dojo.cal.iCalendar.Standard = function (body) {
238
	this.name = "STANDARD";
239
	this._ValidProperties = StandardProperties;
240
	dojo.cal.iCalendar.Component.call(this, body);
241
};
242
dojo.inherits(dojo.cal.iCalendar.Standard, dojo.cal.iCalendar.Component);
243
var DaylightProperties = [_P("dtstart", 1, true), _P("tzoffsetto", 1, true), _P("tzoffsetfrom", 1, true), _P("comment"), _P("rdate"), _P("rrule"), _P("tzname")];
244
dojo.cal.iCalendar.Daylight = function (body) {
245
	this.name = "DAYLIGHT";
246
	this._ValidProperties = DaylightProperties;
247
	dojo.cal.iCalendar.Component.call(this, body);
248
};
249
dojo.inherits(dojo.cal.iCalendar.Daylight, dojo.cal.iCalendar.Component);
250
var VEventProperties = [_P("class", 1), _P("created", 1), _P("description", 1), _P("dtstart", 1), _P("geo", 1), _P("last-mod", 1), _P("location", 1), _P("organizer", 1), _P("priority", 1), _P("dtstamp", 1), _P("seq", 1), _P("status", 1), _P("summary", 1), _P("transp", 1), _P("uid", 1), _P("url", 1), _P("recurid", 1), [_P("dtend", 1), _P("duration", 1)], _P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"), _P("exdate"), _P("exrule"), _P("rstatus"), _P("related"), _P("resources"), _P("rdate"), _P("rrule")];
251
dojo.cal.iCalendar.VEvent = function (body) {
252
	this._ValidProperties = VEventProperties;
253
	this.name = "VEVENT";
254
	dojo.cal.iCalendar.Component.call(this, body);
255
	this.recurring = false;
256
	this.startDate = dojo.date.fromIso8601(this.dtstart.value);
257
};
258
dojo.inherits(dojo.cal.iCalendar.VEvent, dojo.cal.iCalendar.Component);
259
dojo.extend(dojo.cal.iCalendar.VEvent, {getDates:function (until) {
260
	var dtstart = this.getDate();
261
	var recurranceSet = [];
262
	var weekdays = ["su", "mo", "tu", "we", "th", "fr", "sa"];
263
	var order = {"daily":1, "weekly":2, "monthly":3, "yearly":4, "byday":1, "bymonthday":1, "byweekno":2, "bymonth":3, "byyearday":4};
264
	for (var x = 0; x < this.rrule.length; x++) {
265
		var rrule = this.rrule[x];
266
		var freq = rrule.freq.toLowerCase();
267
		var interval = 1;
268
		if (rrule.interval > interval) {
269
			interval = rrule.interval;
270
		}
271
		var set = [];
272
		var freqInt = order[freq];
273
		if (rrule.until) {
274
			var tmpUntil = dojo.date.fromIso8601(rrule.until);
275
		} else {
276
			var tmpUntil = until;
277
		}
278
		if (tmpUntil > until) {
279
			tmpUntil = until;
280
		}
281
		if (dtstart < tmpUntil) {
282
			var expandingRules = function () {
283
			};
284
			var cullingRules = function () {
285
			};
286
			expandingRules.length = 0;
287
			cullingRules.length = 0;
288
			switch (freq) {
289
			  case "yearly":
290
				var nextDate = new Date(dtstart);
291
				set.push(nextDate);
292
				while (nextDate < tmpUntil) {
293
					nextDate.setYear(nextDate.getFullYear() + interval);
294
					tmpDate = new Date(nextDate);
295
					if (tmpDate < tmpUntil) {
296
						set.push(tmpDate);
297
					}
298
				}
299
				break;
300
			  case "monthly":
301
				nextDate = new Date(dtstart);
302
				set.push(nextDate);
303
				while (nextDate < tmpUntil) {
304
					nextDate.setMonth(nextDate.getMonth() + interval);
305
					var tmpDate = new Date(nextDate);
306
					if (tmpDate < tmpUntil) {
307
						set.push(tmpDate);
308
					}
309
				}
310
				break;
311
			  case "weekly":
312
				nextDate = new Date(dtstart);
313
				set.push(nextDate);
314
				while (nextDate < tmpUntil) {
315
					nextDate.setDate(nextDate.getDate() + (7 * interval));
316
					var tmpDate = new Date(nextDate);
317
					if (tmpDate < tmpUntil) {
318
						set.push(tmpDate);
319
					}
320
				}
321
				break;
322
			  case "daily":
323
				nextDate = new Date(dtstart);
324
				set.push(nextDate);
325
				while (nextDate < tmpUntil) {
326
					nextDate.setDate(nextDate.getDate() + interval);
327
					var tmpDate = new Date(nextDate);
328
					if (tmpDate < tmpUntil) {
329
						set.push(tmpDate);
330
					}
331
				}
332
				break;
333
			}
334
			if ((rrule["bymonth"]) && (order["bymonth"] < freqInt)) {
335
				for (var z = 0; z < rrule["bymonth"].length; z++) {
336
					if (z == 0) {
337
						for (var zz = 0; zz < set.length; zz++) {
338
							set[zz].setMonth(rrule["bymonth"][z] - 1);
339
						}
340
					} else {
341
						var subset = [];
342
						for (var zz = 0; zz < set.length; zz++) {
343
							var newDate = new Date(set[zz]);
344
							newDate.setMonth(rrule[z]);
345
							subset.push(newDate);
346
						}
347
						tmp = set.concat(subset);
348
						set = tmp;
349
					}
350
				}
351
			}
352
			if (rrule["byweekno"] && !rrule["bymonth"]) {
353
				dojo.debug("TODO: no support for byweekno yet");
354
			}
355
			if (rrule["byyearday"] && !rrule["bymonth"] && !rrule["byweekno"]) {
356
				if (rrule["byyearday"].length > 1) {
357
					var regex = "([+-]?)([0-9]{1,3})";
358
					for (var z = 1; x < rrule["byyearday"].length; z++) {
359
						var regexResult = rrule["byyearday"][z].match(regex);
360
						if (z == 1) {
361
							for (var zz = 0; zz < set.length; zz++) {
362
								if (regexResult[1] == "-") {
363
									dojo.date.setDayOfYear(set[zz], 366 - regexResult[2]);
364
								} else {
365
									dojo.date.setDayOfYear(set[zz], regexResult[2]);
366
								}
367
							}
368
						} else {
369
							var subset = [];
370
							for (var zz = 0; zz < set.length; zz++) {
371
								var newDate = new Date(set[zz]);
372
								if (regexResult[1] == "-") {
373
									dojo.date.setDayOfYear(newDate, 366 - regexResult[2]);
374
								} else {
375
									dojo.date.setDayOfYear(newDate, regexResult[2]);
376
								}
377
								subset.push(newDate);
378
							}
379
							tmp = set.concat(subset);
380
							set = tmp;
381
						}
382
					}
383
				}
384
			}
385
			if (rrule["bymonthday"] && (order["bymonthday"] < freqInt)) {
386
				if (rrule["bymonthday"].length > 0) {
387
					var regex = "([+-]?)([0-9]{1,3})";
388
					for (var z = 0; z < rrule["bymonthday"].length; z++) {
389
						var regexResult = rrule["bymonthday"][z].match(regex);
390
						if (z == 0) {
391
							for (var zz = 0; zz < set.length; zz++) {
392
								if (regexResult[1] == "-") {
393
									if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
394
										set[zz].setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
395
									}
396
								} else {
397
									if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
398
										set[zz].setDate(regexResult[2]);
399
									}
400
								}
401
							}
402
						} else {
403
							var subset = [];
404
							for (var zz = 0; zz < set.length; zz++) {
405
								var newDate = new Date(set[zz]);
406
								if (regexResult[1] == "-") {
407
									if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
408
										newDate.setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
409
									}
410
								} else {
411
									if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
412
										newDate.setDate(regexResult[2]);
413
									}
414
								}
415
								subset.push(newDate);
416
							}
417
							tmp = set.concat(subset);
418
							set = tmp;
419
						}
420
					}
421
				}
422
			}
423
			if (rrule["byday"] && (order["byday"] < freqInt)) {
424
				if (rrule["bymonth"]) {
425
					if (rrule["byday"].length > 0) {
426
						var regex = "([+-]?)([0-9]{0,1}?)([A-Za-z]{1,2})";
427
						for (var z = 0; z < rrule["byday"].length; z++) {
428
							var regexResult = rrule["byday"][z].match(regex);
429
							var occurance = regexResult[2];
430
							var day = regexResult[3].toLowerCase();
431
							if (z == 0) {
432
								for (var zz = 0; zz < set.length; zz++) {
433
									if (regexResult[1] == "-") {
434
										var numDaysFound = 0;
435
										var lastDayOfMonth = dojo.date.getDaysInMonth(set[zz]);
436
										var daysToSubtract = 1;
437
										set[zz].setDate(lastDayOfMonth);
438
										if (weekdays[set[zz].getDay()] == day) {
439
											numDaysFound++;
440
											daysToSubtract = 7;
441
										}
442
										daysToSubtract = 1;
443
										while (numDaysFound < occurance) {
444
											set[zz].setDate(set[zz].getDate() - daysToSubtract);
445
											if (weekdays[set[zz].getDay()] == day) {
446
												numDaysFound++;
447
												daysToSubtract = 7;
448
											}
449
										}
450
									} else {
451
										if (occurance) {
452
											var numDaysFound = 0;
453
											set[zz].setDate(1);
454
											var daysToAdd = 1;
455
											if (weekdays[set[zz].getDay()] == day) {
456
												numDaysFound++;
457
												daysToAdd = 7;
458
											}
459
											while (numDaysFound < occurance) {
460
												set[zz].setDate(set[zz].getDate() + daysToAdd);
461
												if (weekdays[set[zz].getDay()] == day) {
462
													numDaysFound++;
463
													daysToAdd = 7;
464
												}
465
											}
466
										} else {
467
											var numDaysFound = 0;
468
											var subset = [];
469
											lastDayOfMonth = new Date(set[zz]);
470
											var daysInMonth = dojo.date.getDaysInMonth(set[zz]);
471
											lastDayOfMonth.setDate(daysInMonth);
472
											set[zz].setDate(1);
473
											if (weekdays[set[zz].getDay()] == day) {
474
												numDaysFound++;
475
											}
476
											var tmpDate = new Date(set[zz]);
477
											daysToAdd = 1;
478
											while (tmpDate.getDate() < lastDayOfMonth) {
479
												if (weekdays[tmpDate.getDay()] == day) {
480
													numDaysFound++;
481
													if (numDaysFound == 1) {
482
														set[zz] = tmpDate;
483
													} else {
484
														subset.push(tmpDate);
485
														tmpDate = new Date(tmpDate);
486
														daysToAdd = 7;
487
														tmpDate.setDate(tmpDate.getDate() + daysToAdd);
488
													}
489
												} else {
490
													tmpDate.setDate(tmpDate.getDate() + daysToAdd);
491
												}
492
											}
493
											var t = set.concat(subset);
494
											set = t;
495
										}
496
									}
497
								}
498
							} else {
499
								var subset = [];
500
								for (var zz = 0; zz < set.length; zz++) {
501
									var newDate = new Date(set[zz]);
502
									if (regexResult[1] == "-") {
503
										if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
504
											newDate.setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
505
										}
506
									} else {
507
										if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
508
											newDate.setDate(regexResult[2]);
509
										}
510
									}
511
									subset.push(newDate);
512
								}
513
								tmp = set.concat(subset);
514
								set = tmp;
515
							}
516
						}
517
					}
518
				} else {
519
					dojo.debug("TODO: byday within a yearly rule without a bymonth");
520
				}
521
			}
522
			dojo.debug("TODO: Process BYrules for units larger than frequency");
523
			var tmp = recurranceSet.concat(set);
524
			recurranceSet = tmp;
525
		}
526
	}
527
	recurranceSet.push(dtstart);
528
	return recurranceSet;
529
}, getDate:function () {
530
	return dojo.date.fromIso8601(this.dtstart.value);
531
}});
532
var VTimeZoneProperties = [_P("tzid", 1, true), _P("last-mod", 1), _P("tzurl", 1)];
533
dojo.cal.iCalendar.VTimeZone = function (body) {
534
	this.name = "VTIMEZONE";
535
	this._ValidProperties = VTimeZoneProperties;
536
	dojo.cal.iCalendar.Component.call(this, body);
537
};
538
dojo.inherits(dojo.cal.iCalendar.VTimeZone, dojo.cal.iCalendar.Component);
539
var VTodoProperties = [_P("class", 1), _P("completed", 1), _P("created", 1), _P("description", 1), _P("dtstart", 1), _P("geo", 1), _P("last-mod", 1), _P("location", 1), _P("organizer", 1), _P("percent", 1), _P("priority", 1), _P("dtstamp", 1), _P("seq", 1), _P("status", 1), _P("summary", 1), _P("uid", 1), _P("url", 1), _P("recurid", 1), [_P("due", 1), _P("duration", 1)], _P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"), _P("exdate"), _P("exrule"), _P("rstatus"), _P("related"), _P("resources"), _P("rdate"), _P("rrule")];
540
dojo.cal.iCalendar.VTodo = function (body) {
541
	this.name = "VTODO";
542
	this._ValidProperties = VTodoProperties;
543
	dojo.cal.iCalendar.Component.call(this, body);
544
};
545
dojo.inherits(dojo.cal.iCalendar.VTodo, dojo.cal.iCalendar.Component);
546
var VJournalProperties = [_P("class", 1), _P("created", 1), _P("description", 1), _P("dtstart", 1), _P("last-mod", 1), _P("organizer", 1), _P("dtstamp", 1), _P("seq", 1), _P("status", 1), _P("summary", 1), _P("uid", 1), _P("url", 1), _P("recurid", 1), _P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"), _P("exdate"), _P("exrule"), _P("related"), _P("rstatus"), _P("rdate"), _P("rrule")];
547
dojo.cal.iCalendar.VJournal = function (body) {
548
	this.name = "VJOURNAL";
549
	this._ValidProperties = VJournalProperties;
550
	dojo.cal.iCalendar.Component.call(this, body);
551
};
552
dojo.inherits(dojo.cal.iCalendar.VJournal, dojo.cal.iCalendar.Component);
553
var VFreeBusyProperties = [_P("contact"), _P("dtstart", 1), _P("dtend"), _P("duration"), _P("organizer", 1), _P("dtstamp", 1), _P("uid", 1), _P("url", 1), _P("attendee"), _P("comment"), _P("freebusy"), _P("rstatus")];
554
dojo.cal.iCalendar.VFreeBusy = function (body) {
555
	this.name = "VFREEBUSY";
556
	this._ValidProperties = VFreeBusyProperties;
557
	dojo.cal.iCalendar.Component.call(this, body);
558
};
559
dojo.inherits(dojo.cal.iCalendar.VFreeBusy, dojo.cal.iCalendar.Component);
560
var VAlarmProperties = [[_P("action", 1, true), _P("trigger", 1, true), [_P("duration", 1), _P("repeat", 1)], _P("attach", 1)], [_P("action", 1, true), _P("description", 1, true), _P("trigger", 1, true), [_P("duration", 1), _P("repeat", 1)]], [_P("action", 1, true), _P("description", 1, true), _P("trigger", 1, true), _P("summary", 1, true), _P("attendee", "*", true), [_P("duration", 1), _P("repeat", 1)], _P("attach", 1)], [_P("action", 1, true), _P("attach", 1, true), _P("trigger", 1, true), [_P("duration", 1), _P("repeat", 1)], _P("description", 1)]];
561
dojo.cal.iCalendar.VAlarm = function (body) {
562
	this.name = "VALARM";
563
	this._ValidProperties = VAlarmProperties;
564
	dojo.cal.iCalendar.Component.call(this, body);
565
};
566
dojo.inherits(dojo.cal.iCalendar.VAlarm, dojo.cal.iCalendar.Component);
567