diff options
author | ivan <ivan> | 2004-03-11 02:05:38 +0000 |
---|---|---|
committer | ivan <ivan> | 2004-03-11 02:05:38 +0000 |
commit | 289340780927b5bac2c7604d7317c3063c6dd8cc (patch) | |
tree | c4100ab9857ae00c330213af8a46e66c208580e6 | |
parent | 945721f48f74d5cfffef7c7cf3a3d6bc2521f5dd (diff) |
import of rt 3.0.9RT_3_0_9
165 files changed, 22771 insertions, 4098 deletions
diff --git a/rt/Changelog b/rt/Changelog index d8d73fd6d..0f6bd10c3 100644 --- a/rt/Changelog +++ b/rt/Changelog @@ -2,7 +2,7 @@ Project "rt.3", Branch 0 Page 1 -Change Log Sat Jul 12 04:24:41 2003 +Change Log Fri Feb 13 12:31:27 2004 rt.3.D000, C0, jesse, Thu Mar 13 20:43:23 2003, RT: Request Tracker, branch 3.0. RT: Request Tracker, branch 3.0. @@ -207,6 +207,1633 @@ rt.3.D000, C0, jesse, Thu Mar 13 20:43:23 2003, RT: Request Tracker, branch 3.0. 199 150 README updates to indicate deprecated dependencies 200 151 Debugging framework cleanup 201 152 Bumping version to 3.0.4 + 195 153 #3042: Make max inline body size configurable + 196 154 #3029 - better warning message on improper perms on mail in + 202 155 Initial commit of new commandline client support code + 203 156 More updates to the commandline client + 205 157 Removing ancient cli code that was accidentally added to the + repository + 206 158 Extended ACL edit routines to make it easier to use generic + routines in 3rd party apps + 24 159 Certain ACL checks could fail on postgres due to a marshalling + bug + 209 160 #1751: update second page in Bulk update + 208 161 #1651: URIs not escaped in ticket display + 210 162 A couple of fixes to better deal with creation of 'blank' + ticket requestors + 207 163 regression tests: use $RT::WebPath and RT_LIB_PATH + 211 164 Requestor searches had an extra join that they didn't need + 212 165 License tagger was tagging Makefile, not Makefile.in. + Reconfigured. + 213 166 Bumping to 3.0.5pre1 + 215 167 Merging internationalization fixes from ourinternet + 216 168 #2692: make $Domain an argument for SelectGroups + 219 169 #2855: User_Overlay and Template_Overlay fixes + 220 170 #2989: regexp changes for Subject and loop-detection + 221 171 3158: user can delete only with DeleteTicket right + 222 172 fixes for the importer + 223 173 Adding the RT coding style guide to the distribution + 225 174 One I18N 'fix' from ourinternet tainted attachment data, + breaking tests + 226 175 Code to catch execution problems within RT's web app server + was made more robust + 34 176 Failed user creation didn't always properly roll-back the + database + 227 177 [fsck.com #2378] personal permissions for installation + 228 178 #3199: normalize custom fields searching syntax - Global CF's + previously didn't allow the { } + 229 179 #3201: Perform more clever joining to enhance custom field + search results + 40 180 #3200 - AND MultipleSelect CFs together - OR all other CFs + together. + 42 181 Bumping version to 3.0.5-pre2 + 41 182 #3022: Update to German translation + 43 183 #3068: Better setting of Due dates via the web ui + 44 184 #3131: Preliminary support for Oracle from Brook Schonfield + 45 185 #3152: Updated russian .po file + 46 186 #2792: When finding out if someone is a queue watcher, check + groups recursively + 47 187 Bumping to 3.0.5pre3 + 49 188 Dependencies updated; performance and memory usage fixes for + ticket creation memory usage + 231 189 #3237: Queue-specific templates with the same name as global + templates will now override the globals for queue-related + scrips + 54 190 #3279: Make fsck.com-rt: URIs case insensitive + 230 191 #3230: Parser patch to make watchers searches more efficient + 218 192 #2955: wrapping in messagebox + 232 193 Old relationship update transactions weren't properly + displayed + 237 194 #2672: custom field values ordering + 235 195 #2653: Email.pm patch + 238 196 #3114: allow longer subject lines for postgres + 233 197 #3242: cannonicalize addresses in comments + 236 198 #3278: occasional internal server error in RT.pm + 239 199 #3309: switch lines in User/Prefs.html + 250 200 #3329: Email.pm patch + 252 201 #2687: add ticket subject to resolved template + 255 202 #2268: align fields in User/Prefs.html + 256 203 #2160: clarify that box deletes scrips + 259 204 #2773: don't allow searching for deleted tickets + 257 205 #2700: configurable home page ticket list length + 258 206 #2409: colons after labels in Create.html + 261 207 #3240: DeleteWatcher, not DelWatcher + 262 208 #3143: Italian translation + 251 209 #2617: custom field ordering + 260 210 #2558: allow access to CFs with no name + 263 211 #3281: form actions must not be paths + 266 212 #2693: show proper id in menu after creation + 265 213 #3118: change default unset mail address + 267 214 #3324: Apache::DBI must be 0.92 or newer + 253 215 Fixing improperly applied custom field editing patches + 268 216 Bumping version to 3.0.5pre4 + 269 217 #3341: edit comments in SiteConfig + 271 218 #3012: vertical alignment in Ticket/Elements/ShowPeople + 270 219 #3349: umlauts aren't correct in subject + 272 220 #3236: allow attachments without other txn contents + 273 221 #3105: CreateTickets doesn't set ticket type + 275 222 #3384: recursive merge patches + 276 223 #3354: an additional fix for avoiding the morning bug + 277 224 #3114: increase subject length in non-Postgres dbs + 278 225 Fixes to attempt to stop mysql 'morning bugs' with mysql + 280 226 Post 3.0.5pre3 - sometimes silently losing mail. fixed a + possible bug, improved testing + 281 227 More explicit warning about a lack of perl 5.8 + 282 228 fixing the new testdeps thing + 279 229 #2651: localize die/warn handlers + 64 230 Bumping to 3.0.5pre5 + 283 231 #3399: Message parsing fails for some types of report + 285 232 Better handling of apparently bogus email; rationalize mail + gateway error codes + 286 233 Bumping to 3.0.5pre6 + 287 234 Bumping to 3.0.5RC1 + 288 235 Patches to the cli from ams + 289 236 Custom field values couldn't be set to '0'; README updated for + apache2 + 290 237 RT 3.0.5 + 291 238 Fixing a couple bugs related to display of links + 292 239 fixing a multiple-signature-inclusion bug + 293 240 Bumping to 3.0.6RC1 + 295 241 Updated documentation for RT CLI tool + 296 242 Bumping to RT 3.0.6 + 297 243 Conditionalizing Text::Quoted display, so as to avoid utf8 + crashes + 299 244 Merging bugfixes from ourinternet + 300 245 A bunch of postgres correctness fixes + 301 246 #2346: Resolving a deprecation warning + 84 247 #3981: Ticket creation syntax fix + 298 248 bps #1032: SelfService fixes + 302 249 #3889: add/del fixes + 303 250 #3822: Fix for cli bug (Inapropriate use of arrayref) + 305 251 #3807: CLI example updates + 306 252 #3907: New default templates for user, ticket and queue + 308 253 More reference weakening + 307 254 User objects weren't always destroyed, due to a circular + reference + 310 255 Slightly better debugging on failure to send mail + 94 256 Deep recursion issue on localization handle; missing language + selector + 313 257 Adding back missing SelectLang + 311 258 #3566: EditCustomField supports Default for FreeformSingle + 312 259 Initial Informix port from akso.de + 316 260 #3765: TicketsSQL is case-sensitive + 317 261 #3613: searching on NOT LIKE + 318 262 #3877: don't strip multi-line headers + 319 263 #3551: Create values corrupted when adding new files + 321 264 #3993: warn when installing with mod_perl2 + 320 265 #4087: allow non-ISO dates in transaction searches + 322 266 #3439: custom fields patch + 323 267 #3855: require Locale::Maketext::Lexicon 0.31 + 325 268 #3856: /REST/1.0/search/tickets should work in UTC + 326 269 #3827: regression shouldn't drop db + 327 270 #3801: note when transaction content is ellided + 328 271 #3751: ParseNewMessageForTicketCcs + 332 272 #3776: new indices + 329 273 #3674: autohandler patch + 336 274 New schema relationships diagram in .dot format + 337 275 more work on the schema diagram + 330 276 #3601: SelectRights patch + 331 277 #3583: set Last Contacted date + 333 278 #4088: Postgres performance improvements + 335 279 fix attachment links in base RT + 338 280 Updating storable dependency, to keep redhat 9 users from + hurting themselves + 339 281 Small fix to ticket searching to cut down on # of joins needed + 104 282 Merging ourinternet's changes relative to 3.0.7pre2; UPGRADING + update; postgres installation fixes + 350 283 Bumping version to 3.0.7pre3 + 351 284 CLI changes + 352 285 CLI usage updates + 353 286 Bumping to 3.0.7rc1 + 361 287 Bumping to 3.0.7; Updated DBIx::SearchBuilder dependency + 362 288 Fixes to RT 3.0.7 upgrade instructions; Bumping to 3.0.7_01 + 355 289 Minor cleanups to RT cli tool + 356 290 Fixup to rt-setup-database tool for local schema + 357 291 Display.html takes TicketObj; Update.html uses it + 358 292 localization for link text, not whole link + 359 293 ProcessTicketCustomFieldUpdates takes TicketObj + 360 294 Transaction batching + 363 295 protect against reentrancy in Ticket::DESTROY + 365 296 FastCGI fix to make the CLI work + 366 297 #4415: Fix for imporeting merged tickets + 368 298 Regression and upgrade cleanups + 367 299 Ticket creation and updates via the Web UI were sometimes + encoded wrong + 369 300 CLI tool should pass through orderby arg + 370 301 Bumping to 3.0.8pre1 + 371 302 none + 372 303 Decode uuencoded attachments + 373 304 Fixing next/prev ticket navigation (#4461) it sometimes + disappeared. + 375 305 Ticket counts became inaccurate after repeated web searches + 376 306 Certain non-western From: headers were being mangled + 377 307 Numerous CLI improvements + 378 308 Bumping to 3.0.8pre2 + 379 309 Switching to new I18NSafe lowercasing behaviour for Pg + 380 310 Adding a new index doubles my performance on /index.html + 381 311 Importing fixes from ourinternet + 382 312 Researching email corruption + 197 313 Fixing CreaetTickets documentation + 383 314 #4572: Fix searching on links + 385 315 #4554: callbacks should be ordered + 386 316 #4552 arguments for AddCustomFieldValues + 387 317 #4455: Better handling of bad link URIs + 388 318 #3725: Making CLI display newly created tickets ids + 389 319 #3736: Backport RT 3.1 'inplace' layout + 390 320 #3813: the CreateTickets scripaction couldn't handle + customfields + 391 321 #3608: search by ccs and adminccs in addition to requestors + 114 322 #3066: crontool docs + 393 323 #4711: search ON Dates + 392 324 order SelfService tickets by numeric id + 395 325 Bumping to 3.0.8RC1 + 396 326 AutoOpen should set correct type for Status transaction + 397 327 Fixing apparent SQL error on logout. Actually bug in + localization + 21 328 #2587: turn off autocomplete in RT's search box + 309 329 #3660: add a 'timeout' flag to the rt-mailgate + 315 330 #3608: fixing quicksearch to work with new watcher search + 398 331 Allow RT::CurrentUser to load objects based on RT::User + objects passed in; Backported a fix to the Language Selector + for non-traditional languages; bumped to 3.0.8 + 399 332 Searching for role groups generated queries that were way too + complex + 48 333 First cut at new oracle code from Netzah + 501 334 Adding UTF8 support for oracle; Oracle install instructions; + searchbuilder dep bumped; bumping to 3.0.9pre2 + 502 335 Deleted tickets should never be found in searches + 503 336 #5212 Unicode issues with incoming mail with a charset or + encoding of UTF-8 (caps) + 500 337 Reversing our no-cache pragmas, since IE can't cope with them + over SSL + 506 338 A couple of perf fixes from autrijus which _require_ + SearchBuilder 0.97. Reduces long ticket display by 30% + 508 339 Bumping to 3.0.9pre3 + 509 340 RT now uses progressive rendering by default AND no longer + blocks the load of the CSS sheet; 3.0.9pre4 + 511 341 Optimizing column loads from autrijus' new column load patches + 512 342 Bumping to 3.0.9pre5 + 513 343 More performance work listing ticket Attachments + 515 344 Turning off autoflush for ticket attachments so we can a + content type + 516 345 #5178: Use less verbose html for ticket history + 517 346 Bumping to 3.0.9pre6 + 518 347 Improved next/prev handling for merged tickets + 519 348 Bumping to 3.0.9 - Noting preference for perl 5.8.3 + + rt.3.0.D348, C519, jesse, Fri Feb 13 12:30:42 2004, Bumping to 3.0.9 - Noting + preference for perl 5.8.3 + none + + rt.3.0.D347, C518, jesse, Thu Feb 12 00:21:35 2004, Improved next/prev + handling for merged tickets + From: Jesse <jesse@bitsy> + Date: Thu Feb 12 00:20:40 2004 + + none + + rt.3.0.D346, C517, jesse, Tue Feb 10 00:22:11 2004, Bumping to 3.0.9pre6 + From: Jesse <jesse@bitsy> + Date: Tue Feb 10 00:21:24 2004 + Warning: the original change was in the 'being_integrated' state + + none + + rt.3.0.D345, C516, jesse, Tue Feb 10 00:19:50 2004, #5178: Use less verbose + html for ticket history + From: Jesse <jesse@bitsy> + Date: Tue Feb 10 00:18:57 2004 + + none + + rt.3.0.D344, C515, jesse, Tue Feb 10 00:07:41 2004, Turning off autoflush for + ticket attachments so we can a content type + From: Jesse <jesse@bitsy> + Date: Tue Feb 10 00:02:40 2004 + + none + + rt.3.0.D343, C513, jesse, Mon Feb 9 23:48:40 2004, More performance work + listing ticket Attachments + From: Jesse <jesse@bitsy> + Date: Mon Feb 9 23:48:07 2004 + + none + + rt.3.0.D342, C512, jesse, Fri Feb 6 02:05:13 2004, Bumping to 3.0.9pre5 + none + + rt.3.0.D341, C511, jesse, Thu Feb 5 23:11:20 2004, Optimizing column loads + from autrijus' new column load patches + none + + rt.3.0.D340, C509, jesse, Wed Feb 4 17:56:57 2004, RT now uses progressive + rendering by default AND no longer blocks the load of the CSS sheet; 3.0.9pre4 + none + + rt.3.0.D339, C508, jesse, Wed Feb 4 16:42:08 2004, Bumping to 3.0.9pre3 + none + + rt.3.0.D338, C506, jesse, Wed Feb 4 15:06:36 2004, A couple of perf fixes + from autrijus which _require_ SearchBuilder 0.97. Reduces long ticket display + by 30% + none + + rt.3.0.D337, C500, jesse, Sun Feb 1 15:01:39 2004, Reversing our no-cache + pragmas, since IE can't cope with them over SSL + none + + rt.3.0.D336, C503, jesse, Wed Jan 28 19:56:55 2004, #5212 Unicode issues with + incoming mail with a charset or encoding of UTF-8 (caps) + none + + rt.3.0.D335, C502, jesse, Wed Jan 28 19:24:48 2004, Deleted tickets should + never be found in searches + none + + rt.3.0.D334, C501, jesse, Thu Jan 8 15:21:02 2004, Adding UTF8 support for + oracle; Oracle install instructions; searchbuilder dep bumped; bumping to + 3.0.9pre2 + none + + rt.3.0.D333, C48, jesse, Sun Jan 4 23:18:16 2004, First cut at new oracle + code from Netzah + From: Jesse <jesse@bitsy> + Date: Sun Jan 4 23:17:21 2004 + + none + + rt.3.0.D332, C399, jesse, Sat Jan 3 15:57:44 2004, Searching for role groups + generated queries that were way too complex + From: Jesse <jesse@bitsy> + Date: Sat Jan 3 15:57:50 2004 + + none + + rt.3.0.D331, C398, jesse, Fri Jan 2 16:22:47 2004, Allow RT::CurrentUser to + load objects based on RT::User objects passed in; Backported a fix to the + Language Selector for non-traditional languages; bumped to 3.0.8 + From: Jesse <jesse@bitsy> + Date: Fri Jan 2 16:22:55 2004 + + none + + rt.3.0.D330, C315, jesse, Fri Jan 2 15:10:37 2004, #3608: fixing quicksearch + to work with new watcher search + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 15:31:06 2003 + + none + + rt.3.0.D329, C309, jesse, Fri Jan 2 15:10:02 2004, #3660: add a 'timeout' + flag to the rt-mailgate + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 02:12:05 2003 + + none + + rt.3.0.D328, C21, jesse, Fri Jan 2 15:09:18 2004, #2587: turn off + autocomplete in RT's search box + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 01:57:52 2003 + + none + + rt.3.0.D327, C397, jesse, Tue Dec 30 16:19:24 2003, Fixing apparent SQL error + on logout. Actually bug in localization + none + + rt.3.0.D326, C396, leira, Fri Dec 19 01:11:25 2003, AutoOpen should set + correct type for Status transaction + From: Linda L. Julien <leira@starsong.org> + Date: Thu Dec 18 23:56:15 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D325, C395, jesse, Wed Dec 17 14:12:38 2003, Bumping to 3.0.8RC1 + From: Jesse <jesse@bitsy> + Date: Thu Dec 18 15:00:12 2003 + + none + + rt.3.0.D324, C392, leira, Wed Dec 17 14:09:47 2003, order SelfService tickets + by numeric id + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Dec 15 04:21:15 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D323, C393, jesse, Mon Dec 15 19:28:46 2003, #4711: search ON Dates + From: Jesse <jesse@bitsy> + Date: Tue Dec 16 20:30:27 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D322, C114, jesse, Sat Dec 13 01:32:42 2003, #3066: crontool docs + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 00:38:04 2003 + + none + + rt.3.0.D321, C391, jesse, Sat Dec 13 01:32:12 2003, #3608: search by ccs and + adminccs in addition to requestors + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 01:24:33 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D320, C390, jesse, Sat Dec 13 01:29:24 2003, #3813: the CreateTickets + scripaction couldn't handle customfields + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 01:22:56 2003 + + none + + rt.3.0.D319, C389, jesse, Sat Dec 13 01:28:24 2003, #3736: Backport RT 3.1 + 'inplace' layout + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 01:15:39 2003 + + none + + rt.3.0.D318, C388, jesse, Sat Dec 13 01:28:13 2003, #3725: Making CLI display + newly created tickets ids + From: Jesse Vincent <jesse@hostname> + Date: Sat Dec 13 01:12:20 2003 + + none + + rt.3.0.D317, C387, jesse, Sat Dec 13 01:27:59 2003, #4455: Better handling of + bad link URIs + From: Jesse Vincent <jesse@hostname> + Date: Fri Dec 12 23:33:09 2003 + + none + + rt.3.0.D316, C386, jesse, Sat Dec 13 01:27:41 2003, #4552 arguments for + AddCustomFieldValues + From: Jesse Vincent <jesse@hostname> + Date: Fri Dec 12 23:23:08 2003 + + none + + rt.3.0.D315, C385, jesse, Sat Dec 13 01:27:17 2003, #4554: callbacks should be + ordered + From: Jesse Vincent <jesse@hostname> + Date: Fri Dec 12 23:14:57 2003 + + none + + rt.3.0.D314, C383, jesse, Sat Dec 13 01:27:06 2003, #4572: Fix searching on + links + From: Jesse Vincent <jesse@hostname> + Date: Fri Dec 12 23:11:24 2003 + + none + + rt.3.0.D313, C197, jesse, Fri Dec 12 23:18:59 2003, Fixing CreaetTickets + documentation + From: Jesse Vincent <jesse@localhost> + Date: Tue Jul 8 19:59:48 2003 + + none + + rt.3.0.D312, C382, jesse, Thu Dec 11 12:58:27 2003, Researching email + corruption + From: Jesse <jesse@bitsy> + Date: Fri Dec 12 14:02:37 2003 + + none + + rt.3.0.D311, C381, jesse, Mon Dec 8 03:06:53 2003, Importing fixes from + ourinternet + From: Jesse <jesse@bitsy> + Date: Tue Dec 9 04:10:35 2003 + + none + + rt.3.0.D310, C380, jesse, Mon Dec 8 02:52:37 2003, Adding a new index doubles + my performance on /index.html + From: Jesse <jesse@bitsy> + Date: Tue Dec 9 03:53:40 2003 + + none + + rt.3.0.D309, C379, jesse, Sat Dec 6 21:06:31 2003, Switching to new I18NSafe + lowercasing behaviour for Pg + From: Jesse <jesse@bitsy> + Date: Sun Dec 7 22:11:09 2003 + + none + + rt.3.0.D308, C378, jesse, Fri Dec 5 16:51:11 2003, Bumping to 3.0.8pre2 + From: Jesse <jesse@bitsy> + Date: Sat Dec 6 17:43:47 2003 + + none + + rt.3.0.D307, C377, leira, Fri Dec 5 16:45:20 2003, Numerous CLI improvements + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Dec 5 03:09:04 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D306, C376, jesse, Wed Dec 3 01:15:23 2003, Certain non-western From: + headers were being mangled + From: Jesse Vincent <jesse@hostname> + Date: Wed Dec 3 01:14:25 2003 + + none + + rt.3.0.D305, C375, jesse, Tue Dec 2 19:05:41 2003, Ticket counts became + inaccurate after repeated web searches + From: Jesse Vincent <jesse@hostname> + Date: Tue Dec 2 19:03:18 2003 + + none + + rt.3.0.D304, C373, jesse, Tue Dec 2 18:36:05 2003, Fixing next/prev ticket + navigation (#4461) it sometimes disappeared. + From: Jesse Vincent <jesse@hostname> + Date: Tue Dec 2 18:34:07 2003 + + none + + rt.3.0.D303, C372, jesse, Thu Nov 27 12:28:56 2003, Decode uuencoded + attachments + From: Jesse <jesse@bitsy> + Date: Fri Nov 28 13:32:25 2003 + + none + + rt.3.0.D302, C371, jesse, Thu Nov 27 02:00:59 2003, none + From: Jesse <jesse@bitsy> + Date: Fri Nov 28 03:05:10 2003 + + none + + rt.3.0.D301, C370, jesse, Tue Nov 25 22:24:45 2003, Bumping to 3.0.8pre1 + none + + rt.3.0.D300, C369, leira, Fri Nov 21 12:30:08 2003, CLI tool should pass + through orderby arg + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Nov 21 12:22:20 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D299, C367, jesse, Fri Nov 21 00:24:44 2003, Ticket creation and + updates via the Web UI were sometimes encoded wrong + From: Jesse <jesse@bitsy> + Date: Sat Nov 22 01:17:10 2003 + + none + + rt.3.0.D298, C368, jesse, Fri Nov 21 00:21:32 2003, Regression and upgrade + cleanups + From: Jesse <jesse@bitsy> + Date: Sat Nov 22 01:20:08 2003 + + none + + rt.3.0.D297, C366, jesse, Thu Nov 20 17:44:16 2003, #4415: Fix for imporeting + merged tickets + From: Jesse <jesse@bitsy> + Date: Fri Nov 21 18:47:53 2003 + + none + + rt.3.0.D296, C365, jesse, Thu Nov 20 17:22:51 2003, FastCGI fix to make the + CLI work + From: Jesse <jesse@bitsy> + Date: Fri Nov 21 18:24:18 2003 + + none + + rt.3.0.D295, C363, leira, Thu Nov 20 17:21:32 2003, protect against reentrancy + in Ticket::DESTROY + From: Linda L. Julien <leira@starsong.org> + Date: Wed Nov 19 15:45:47 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D294, C360, leira, Mon Nov 17 23:28:48 2003, Transaction batching + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Nov 17 18:52:37 2003 + Warning: the original change was in the 'being_developed' state + + From: Jesse <jesse@bitsy> + Date: Sun Nov 16 18:10:00 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D293, C359, leira, Mon Nov 17 23:24:21 2003, + ProcessTicketCustomFieldUpdates takes TicketObj + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Nov 17 17:59:28 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D292, C358, leira, Mon Nov 17 23:21:05 2003, localization for link + text, not whole link + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Nov 17 17:33:58 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D291, C357, leira, Mon Nov 17 23:20:32 2003, Display.html takes + TicketObj; Update.html uses it + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Nov 17 17:19:05 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D290, C356, leira, Mon Nov 17 23:16:11 2003, Fixup to rt-setup-database + tool for local schema + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Nov 17 15:30:46 2003 + Warning: the original change was in the 'awaiting_integration' state + + From: Jesse <jesse@bitsy> + Date: Sun Nov 16 18:09:16 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D289, C355, leira, Mon Nov 17 23:14:05 2003, Minor cleanups to RT cli + tool + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Nov 17 14:59:54 2003 + Warning: the original change was in the 'awaiting_integration' state + + From: Jesse <jesse@bitsy> + Date: Sun Nov 16 18:09:22 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D288, C362, jesse, Mon Nov 17 22:53:56 2003, Fixes to RT 3.0.7 upgrade + instructions; Bumping to 3.0.7_01 + From: Jesse <jesse@bitsy> + Date: Tue Nov 18 23:56:48 2003 + + none + + rt.3.0.D287, C361, jesse, Mon Nov 17 19:30:11 2003, Bumping to 3.0.7; Updated + DBIx::SearchBuilder dependency + From: Jesse <jesse@bitsy> + Date: Tue Nov 18 20:25:24 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D286, C353, jesse, Thu Nov 13 03:11:35 2003, Bumping to 3.0.7rc1 + From: Jesse <jesse@bitsy> + Date: Fri Nov 14 04:13:34 2003 + + none + + rt.3.0.D285, C352, jesse, Thu Nov 13 02:59:36 2003, CLI usage updates + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Nov 13 02:58:17 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D284, C351, leira, Thu Nov 13 02:41:21 2003, CLI changes + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Nov 13 02:36:17 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D283, C350, jesse, Mon Nov 10 01:26:11 2003, Bumping version to + 3.0.7pre3 + From: Jesse Vincent <jesse@hostname> + Date: Mon Nov 10 01:24:27 2003 + + none + + rt.3.0.D282, C104, jesse, Mon Nov 10 01:16:01 2003, Merging ourinternet's + changes relative to 3.0.7pre2; UPGRADING update; postgres installation fixes + From: Jesse Vincent <jesse@hostname> + Date: Mon Nov 10 01:10:08 2003 + + none + + rt.3.0.D281, C339, jesse, Thu Nov 6 21:11:46 2003, Small fix to ticket + searching to cut down on # of joins needed + From: Jesse Vincent <jesse@hostname> + Date: Thu Nov 6 21:11:21 2003 + + none + + rt.3.0.D280, C338, jesse, Thu Nov 6 21:05:17 2003, Updating storable + dependency, to keep redhat 9 users from hurting themselves + From: Jesse Vincent <jesse@hostname> + Date: Thu Nov 6 20:53:44 2003 + + none + + rt.3.0.D279, C335, leira, Tue Nov 4 21:11:39 2003, fix attachment links in + base RT + From: Linda L. Julien <leira@starsong.org> + Date: Tue Nov 4 16:42:55 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D278, C333, leira, Tue Nov 4 21:10:18 2003, #4088: Postgres + performance improvements + From: Linda L. Julien <leira@starsong.org> + Date: Tue Nov 4 16:25:57 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D277, C331, leira, Tue Nov 4 21:08:27 2003, #3583: set Last Contacted + date + From: Linda L. Julien <leira@starsong.org> + Date: Mon Nov 3 13:58:57 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D276, C330, leira, Tue Nov 4 21:06:14 2003, #3601: SelectRights patch + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 22:03:23 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D275, C337, jesse, Tue Nov 4 18:18:39 2003, more work on the schema + diagram + From: Jesse Vincent <jesse@hostname> + Date: Tue Nov 4 18:16:53 2003 + + none + + rt.3.0.D274, C336, jesse, Tue Nov 4 18:18:24 2003, New schema relationships + diagram in .dot format + From: Jesse Vincent <jesse@hostname> + Date: Tue Nov 4 17:51:10 2003 + + none + + rt.3.0.D273, C329, leira, Tue Nov 4 17:52:14 2003, #3674: autohandler patch + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 21:49:43 2003 + + none + + rt.3.0.D272, C332, leira, Tue Nov 4 17:29:08 2003, #3776: new indices + From: Linda L. Julien <leira@starsong.org> + Date: Tue Nov 4 15:25:39 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D271, C328, leira, Sun Nov 2 23:07:51 2003, #3751: + ParseNewMessageForTicketCcs + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 21:16:07 2003 + + none + + rt.3.0.D270, C327, leira, Sun Nov 2 22:49:39 2003, #3801: note when + transaction content is ellided + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 20:44:58 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D269, C326, leira, Sun Nov 2 22:31:42 2003, #3827: regression + shouldn't drop db + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 20:17:48 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D268, C325, leira, Sun Nov 2 21:15:22 2003, #3856: /REST/1.0/search/ + tickets should work in UTC + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 19:57:19 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D267, C323, leira, Sun Nov 2 21:14:48 2003, #3855: require + Locale::Maketext::Lexicon 0.31 + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 19:36:37 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D266, C322, leira, Sun Nov 2 21:14:18 2003, #3439: custom fields patch + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 19:11:11 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D265, C320, leira, Sun Nov 2 20:00:45 2003, #4087: allow non-ISO dates + in transaction searches + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 18:28:45 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D264, C321, leira, Sun Nov 2 19:59:21 2003, #3993: warn when + installing with mod_perl2 + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 18:47:57 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D263, C319, leira, Sun Nov 2 18:51:11 2003, #3551: Create values + corrupted when adding new files + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 17:36:44 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D262, C318, leira, Sun Nov 2 18:50:09 2003, #3877: don't strip multi- + line headers + From: Linda L. Julien <leira@starsong.org> + Date: Sun Nov 2 16:32:21 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D261, C317, leira, Sun Nov 2 18:49:15 2003, #3613: searching on NOT + LIKE + From: Linda L. Julien <leira@starsong.org> + Date: Fri Oct 31 01:39:10 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D260, C316, leira, Fri Oct 31 11:59:11 2003, #3765: TicketsSQL is case- + sensitive + From: Linda L. Julien <leira@starsong.org> + Date: Thu Oct 30 16:46:33 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D259, C312, jesse, Fri Oct 31 11:58:43 2003, Initial Informix port from + akso.de + From: Jesse Vincent <jesse@hostname> + Date: Thu Oct 30 13:03:54 2003 + + none + + rt.3.0.D258, C311, leira, Fri Oct 31 11:57:33 2003, #3566: EditCustomField + supports Default for FreeformSingle + From: Linda L. Julien <leira@starsong.org> + Date: Fri Oct 24 16:48:36 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D257, C313, jesse, Thu Oct 30 15:33:45 2003, Adding back missing + SelectLang + From: Jesse Vincent <jesse@hostname> + Date: Thu Oct 30 15:31:35 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D256, C94, jesse, Tue Oct 28 16:02:50 2003, Deep recursion issue on + localization handle; missing language selector + From: Jesse Vincent <jesse@hostname> + Date: Tue Oct 28 16:01:40 2003 + + none + + rt.3.0.D255, C310, jesse, Wed Oct 22 00:33:40 2003, Slightly better debugging + on failure to send mail + From: Jesse Vincent <jesse@hostname> + Date: Wed Oct 22 00:25:35 2003 + + none + + rt.3.0.D254, C307, jesse, Tue Oct 21 23:43:39 2003, User objects weren't + always destroyed, due to a circular reference + From: Jesse Vincent <jesse@hostname> + Date: Mon Oct 20 19:02:08 2003 + + none + + rt.3.0.D253, C308, jesse, Tue Oct 21 23:35:50 2003, More reference weakening + From: Jesse Vincent <jesse@hostname> + Date: Tue Oct 21 23:34:11 2003 + + none + + rt.3.0.D252, C306, jesse, Sun Oct 19 21:06:33 2003, #3907: New default + templates for user, ticket and queue + From: Jesse Vincent <jesse@hostname> + Date: Sun Oct 19 21:05:48 2003 + + none + + rt.3.0.D251, C305, jesse, Sun Oct 19 21:00:11 2003, #3807: CLI example updates + From: Jesse Vincent <jesse@hostname> + Date: Sun Oct 19 20:59:14 2003 + + none + + rt.3.0.D250, C303, jesse, Sun Oct 19 20:55:45 2003, #3822: Fix for cli bug + (Inapropriate use of arrayref) + From: Jesse Vincent <jesse@hostname> + Date: Sun Oct 19 20:54:22 2003 + + none + + rt.3.0.D249, C302, jesse, Sun Oct 19 20:55:16 2003, #3889: add/del fixes + From: Jesse Vincent <jesse@hostname> + Date: Sun Oct 19 20:25:21 2003 + + none + + rt.3.0.D248, C298, leira, Sun Oct 19 20:23:35 2003, bps #1032: SelfService + fixes + From: Linda Julien <leira@hawthorn.local.> + Date: Wed Oct 8 18:39:07 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D247, C84, jesse, Sun Oct 19 20:23:21 2003, #3981: Ticket creation + syntax fix + From: Jesse Vincent <jesse@hostname> + Date: Sun Oct 19 20:20:46 2003 + + none + + rt.3.0.D246, C301, jesse, Sun Oct 19 20:11:09 2003, #2346: Resolving a + deprecation warning + From: Jesse Vincent <jesse@hostname> + Date: Sun Oct 19 20:10:25 2003 + + none + + rt.3.0.D245, C300, jesse, Thu Oct 16 20:03:36 2003, A bunch of postgres + correctness fixes + From: Jesse Vincent <jesse@hostname> + Date: Thu Oct 16 20:00:27 2003 + + none + + rt.3.0.D244, C299, jesse, Thu Oct 16 20:02:08 2003, Merging bugfixes from + ourinternet + From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.> + Date: Tue Oct 14 12:29:53 2003 + + none + + rt.3.0.D243, C297, jesse, Wed Oct 8 11:47:30 2003, Conditionalizing + Text::Quoted display, so as to avoid utf8 crashes + From: Jesse Vincent <jesse@hostname> + Date: Wed Oct 8 16:46:31 2003 + + none + + rt.3.0.D242, C296, jesse, Thu Sep 25 16:28:46 2003, Bumping to RT 3.0.6 + From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.> + Date: Thu Sep 25 16:27:53 2003 + + none + + rt.3.0.D241, C295, jesse, Thu Sep 25 15:13:08 2003, Updated documentation for + RT CLI tool + From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.> + Date: Thu Sep 25 15:12:46 2003 + + none + + rt.3.0.D240, C293, jesse, Mon Sep 22 16:21:10 2003, Bumping to 3.0.6RC1 + From: Jesse Vincent <jesse@localhost> + Date: Mon Sep 22 16:20:02 2003 + + none + + rt.3.0.D239, C292, jesse, Mon Sep 22 16:21:00 2003, fixing a multiple- + signature-inclusion bug + From: Jesse Vincent <jesse@localhost> + Date: Mon Sep 22 15:29:40 2003 + + none + + rt.3.0.D238, C291, jesse, Mon Sep 22 14:46:52 2003, Fixing a couple bugs + related to display of links + From: Jesse Vincent <jesse@localhost> + Date: Mon Sep 22 14:44:12 2003 + + none + + rt.3.0.D237, C290, jesse, Mon Sep 8 14:18:29 2003, RT 3.0.5 + From: Jesse Vincent <jesse@localhost> + Date: Mon Sep 8 14:12:19 2003 + + none + + rt.3.0.D236, C289, jesse, Mon Sep 8 13:47:05 2003, Custom field values + couldn't be set to '0'; README updated for apache2 + From: Jesse Vincent <jesse@localhost> + Date: Mon Sep 8 13:45:41 2003 + + none + + rt.3.0.D235, C288, jesse, Sat Sep 6 01:52:41 2003, Patches to the cli from + ams + From: Jesse Vincent <jesse@localhost> + Date: Sat Sep 6 01:50:41 2003 + + none + + rt.3.0.D234, C287, jesse, Tue Sep 2 18:16:15 2003, Bumping to 3.0.5RC1 + From: Jesse Vincent <jesse@localhost> + Date: Tue Sep 2 18:15:51 2003 + + none + + rt.3.0.D233, C286, jesse, Fri Aug 29 21:10:44 2003, Bumping to 3.0.5pre6 + From: Jesse Vincent <jesse@localhost> + Date: Fri Aug 29 18:01:40 2003 + + none + + rt.3.0.D232, C285, jesse, Fri Aug 29 21:10:24 2003, Better handling of + apparently bogus email; rationalize mail gateway error codes + From: Jesse Vincent <jesse@localhost> + Date: Fri Aug 29 18:01:29 2003 + + none + + rt.3.0.D231, C283, jesse, Fri Aug 29 16:26:30 2003, #3399: Message parsing + fails for some types of report + From: Jesse Vincent <jesse@localhost> + Date: Fri Aug 29 16:25:33 2003 + + none + + rt.3.0.D230, C64, jesse, Thu Aug 28 17:40:29 2003, Bumping to 3.0.5pre5 + From: Jesse Vincent <jesse@localhost> + Date: Thu Aug 28 17:32:38 2003 + + none + + rt.3.0.D229, C279, leira, Thu Aug 28 17:39:37 2003, #2651: localize die/warn + handlers + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 26 15:38:12 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D228, C282, jesse, Thu Aug 28 17:38:28 2003, fixing the new testdeps + thing + From: Jesse Vincent <jesse@localhost> + Date: Thu Aug 28 17:38:07 2003 + + none + + rt.3.0.D227, C281, jesse, Thu Aug 28 17:34:18 2003, More explicit warning + about a lack of perl 5.8 + From: Jesse Vincent <jesse@localhost> + Date: Thu Aug 28 17:30:47 2003 + + none + + rt.3.0.D226, C280, jesse, Thu Aug 28 17:33:15 2003, Post 3.0.5pre3 - sometimes + silently losing mail. fixed a possible bug, improved testing + From: Jesse Vincent <jesse@localhost> + Date: Thu Aug 28 17:09:51 2003 + + none + + rt.3.0.D225, C278, jesse, Tue Aug 26 15:29:24 2003, Fixes to attempt to stop + mysql 'morning bugs' with mysql + From: Jesse Vincent <jesse@localhost> + Date: Tue Aug 26 15:28:20 2003 + + none + + rt.3.0.D224, C277, leira, Tue Aug 26 15:04:20 2003, #3114: increase subject + length in non-Postgres dbs + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 26 14:51:25 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D223, C276, leira, Tue Aug 26 15:03:17 2003, #3354: an additional fix + for avoiding the morning bug + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Aug 25 17:58:27 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D222, C275, leira, Tue Aug 26 15:02:16 2003, #3384: recursive merge + patches + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Aug 25 17:02:00 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D221, C273, leira, Mon Aug 25 16:33:53 2003, #3105: CreateTickets + doesn't set ticket type + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Aug 25 16:30:06 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D220, C272, leira, Mon Aug 25 15:53:13 2003, #3236: allow attachments + without other txn contents + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Aug 25 15:47:52 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D219, C270, leira, Mon Aug 25 15:13:31 2003, #3349: umlauts aren't + correct in subject + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Aug 25 13:55:52 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D218, C271, leira, Mon Aug 25 15:13:05 2003, #3012: vertical alignment + in Ticket/Elements/ShowPeople + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Aug 25 14:08:04 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D217, C269, leira, Mon Aug 25 14:45:12 2003, #3341: edit comments in + SiteConfig + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Aug 25 13:38:51 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D216, C268, jesse, Sun Aug 24 17:16:04 2003, Bumping version to + 3.0.5pre4 + From: Jesse Vincent <jesse@localhost> + Date: Sun Aug 24 17:15:36 2003 + + none + + rt.3.0.D215, C253, jesse, Sun Aug 24 17:12:37 2003, Fixing improperly applied + custom field editing patches + From: Jesse Vincent <jesse@localhost> + Date: Sun Aug 24 17:11:40 2003 + + none + + rt.3.0.D214, C267, leira, Sun Aug 24 14:57:37 2003, #3324: Apache::DBI must be + 0.92 or newer + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Aug 22 14:40:27 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D213, C265, leira, Fri Aug 22 13:30:09 2003, #3118: change default + unset mail address + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Aug 22 12:13:22 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D212, C266, leira, Fri Aug 22 13:29:46 2003, #2693: show proper id in + menu after creation + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Aug 22 12:39:53 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D211, C263, leira, Fri Aug 22 01:18:00 2003, #3281: form actions must + not be paths + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Aug 22 01:12:07 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D210, C260, leira, Fri Aug 22 01:13:07 2003, #2558: allow access to CFs + with no name + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Aug 21 22:36:35 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D209, C251, leira, Fri Aug 22 01:07:34 2003, #2617: custom field + ordering + From: Linda Julien <leira@hawthorn.local.> + Date: Wed Aug 20 17:33:22 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D208, C262, leira, Fri Aug 22 01:00:21 2003, #3143: Italian translation + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Aug 22 00:52:11 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D207, C261, leira, Thu Aug 21 23:31:22 2003, #3240: DeleteWatcher, not + DelWatcher + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Aug 21 23:22:40 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D206, C258, leira, Thu Aug 21 23:07:01 2003, #2409: colons after labels + in Create.html + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Aug 21 17:23:04 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D205, C257, leira, Thu Aug 21 23:06:12 2003, #2700: configurable home + page ticket list length + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Aug 21 15:08:27 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D204, C259, leira, Thu Aug 21 22:37:27 2003, #2773: don't allow + searching for deleted tickets + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Aug 21 22:15:43 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D203, C256, leira, Thu Aug 21 14:09:59 2003, #2160: clarify that box + deletes scrips + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Aug 21 13:53:00 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D202, C255, leira, Thu Aug 21 14:09:27 2003, #2268: align fields in + User/Prefs.html + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Aug 21 13:21:00 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D201, C252, leira, Wed Aug 20 18:13:50 2003, #2687: add ticket subject + to resolved template + From: Linda Julien <leira@hawthorn.local.> + Date: Wed Aug 20 17:58:22 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D200, C250, leira, Wed Aug 20 13:33:40 2003, #3329: Email.pm patch + From: Linda Julien <leira@hawthorn.local.> + Date: Wed Aug 20 13:19:58 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D199, C239, leira, Tue Aug 19 23:05:34 2003, #3309: switch lines in + User/Prefs.html + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 19 22:59:28 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D198, C236, leira, Tue Aug 19 22:47:07 2003, #3278: occasional internal + server error in RT.pm + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 19 22:44:16 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D197, C233, leira, Tue Aug 19 22:28:05 2003, #3242: cannonicalize + addresses in comments + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 19 22:21:57 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D196, C238, leira, Tue Aug 19 22:07:37 2003, #3114: allow longer + subject lines for postgres + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 19 22:01:02 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D195, C235, leira, Tue Aug 19 21:54:16 2003, #2653: Email.pm patch + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 19 19:57:12 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D194, C237, leira, Tue Aug 19 21:51:11 2003, #2672: custom field values + ordering + From: Linda Julien <leira@hawthorn.local.> + Date: Tue Aug 19 21:19:44 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D193, C232, jesse, Mon Aug 18 22:16:09 2003, Old relationship update + transactions weren't properly displayed + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 18 22:14:33 2003 + + none + + rt.3.0.D192, C218, leira, Thu Aug 14 13:37:04 2003, #2955: wrapping in + messagebox + From: Linda Julien <leira@hawthorn.local.> + Date: Wed Aug 13 17:28:03 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D191, C230, jesse, Tue Aug 12 02:54:11 2003, #3230: Parser patch to + make watchers searches more efficient + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 11 14:41:00 2003 + + none + + rt.3.0.D190, C54, jesse, Tue Aug 12 02:49:27 2003, #3279: Make fsck.com-rt: + URIs case insensitive + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 11 15:25:07 2003 + + none + + rt.3.0.D189, C231, jesse, Tue Aug 12 02:47:19 2003, #3237: Queue-specific + templates with the same name as global templates will now override the globals + for queue-related scrips + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 11 15:04:37 2003 + + none + + rt.3.0.D188, C49, jesse, Fri Aug 8 01:57:57 2003, Dependencies updated; + performance and memory usage fixes for ticket creation memory usage + From: Jesse Vincent <jesse@localhost> + Date: Fri Aug 8 01:54:16 2003 + + none + + rt.3.0.D187, C47, jesse, Mon Aug 4 23:20:33 2003, Bumping to 3.0.5pre3 + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 4 23:20:16 2003 + + none + + rt.3.0.D186, C46, jesse, Mon Aug 4 19:15:22 2003, #2792: When finding out if + someone is a queue watcher, check groups recursively + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 4 19:14:50 2003 + + none + + rt.3.0.D185, C45, jesse, Mon Aug 4 18:55:13 2003, #3152: Updated russian .po + file + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 4 18:50:35 2003 + + none + + rt.3.0.D184, C44, jesse, Mon Aug 4 18:27:40 2003, #3131: Preliminary support + for Oracle from Brook Schonfield + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 4 18:26:08 2003 + + none + + rt.3.0.D183, C43, jesse, Mon Aug 4 16:19:07 2003, #3068: Better setting of + Due dates via the web ui + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 4 16:18:50 2003 + + none + + rt.3.0.D182, C41, jesse, Mon Aug 4 16:02:01 2003, #3022: Update to German + translation + From: Jesse Vincent <jesse@localhost> + Date: Mon Aug 4 16:01:08 2003 + + none + + rt.3.0.D181, C42, jesse, Thu Jul 31 13:34:50 2003, Bumping version to 3.0.5- + pre2 + From: Jesse Vincent <jesse@localhost> + Date: Thu Jul 31 13:28:35 2003 + + none + + rt.3.0.D180, C40, jesse, Tue Jul 29 02:24:22 2003, #3200 - AND MultipleSelect + CFs together - OR all other CFs together. + From: Jesse Vincent <jesse@localhost> + Date: Tue Jul 29 02:21:50 2003 + + none + + rt.3.0.D179, C229, jesse, Tue Jul 29 02:09:06 2003, #3201: Perform more clever + joining to enhance custom field search results + From: Jesse Vincent <jesse@localhost> + Date: Tue Jul 29 02:06:22 2003 + + none + + rt.3.0.D178, C228, jesse, Tue Jul 29 01:17:12 2003, #3199: normalize custom + fields searching syntax - Global CF's previously didn't allow the { } + From: Jesse Vincent <jesse@localhost> + Date: Tue Jul 29 01:16:28 2003 + + none + + rt.3.0.D177, C227, jesse, Mon Jul 28 01:39:28 2003, [fsck.com #2378] personal + permissions for installation + From: Robert <rspier@bear> + Date: Sun Jul 27 22:19:40 2003 + Warning: the original change was in the 'awaiting_integration' state + + install as current user option for configure + + rt.3.0.D176, C34, jesse, Mon Jul 28 00:00:12 2003, Failed user creation didn't + always properly roll-back the database + From: Jesse Vincent <jesse@localhost> + Date: Sun Jul 27 23:59:16 2003 + + none + + rt.3.0.D175, C226, jesse, Sun Jul 27 23:52:28 2003, Code to catch execution + problems within RT's web app server was made more robust + From: Jesse Vincent <jesse@localhost> + Date: Sun Jul 27 23:51:50 2003 + + none + + rt.3.0.D174, C225, jesse, Sun Jul 27 23:44:44 2003, One I18N 'fix' from + ourinternet tainted attachment data, breaking tests + From: Jesse Vincent <jesse@localhost> + Date: Sun Jul 27 23:44:17 2003 + + none + + rt.3.0.D173, C223, jesse, Sun Jul 27 17:16:20 2003, Adding the RT coding style + guide to the distribution + From: Jesse Vincent <jesse@localhost> + Date: Sun Jul 27 17:15:32 2003 + + none + + rt.3.0.D172, C222, jesse, Fri Jul 25 19:50:19 2003, fixes for the importer + From: Jesse Vincent <jesse@localhost> + Date: Fri Jul 25 19:49:06 2003 + + none + + rt.3.0.D171, C221, leira, Fri Jul 25 14:02:49 2003, 3158: user can delete only + with DeleteTicket right + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Jul 25 02:44:41 2003 + Warning: the original change was in the 'being_developed' state + + none + + rt.3.0.D170, C220, leira, Fri Jul 25 14:01:38 2003, #2989: regexp changes for + Subject and loop-detection + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Jul 25 02:02:18 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D169, C219, leira, Fri Jul 25 13:52:47 2003, #2855: User_Overlay and + Template_Overlay fixes + From: Linda Julien <leira@hawthorn.local.> + Date: Fri Jul 25 01:08:37 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D168, C216, leira, Fri Jul 25 13:45:37 2003, #2692: make $Domain an + argument for SelectGroups + From: Linda Julien <leira@hawthorn.local.> + Date: Thu Jul 24 23:31:35 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D167, C215, jesse, Thu Jul 24 23:25:01 2003, Merging + internationalization fixes from ourinternet + From: Jesse Vincent <jesse@localhost> + Date: Thu Jul 24 23:22:46 2003 + + none + + rt.3.0.D166, C213, jesse, Thu Jul 24 18:39:57 2003, Bumping to 3.0.5pre1 + From: Jesse Vincent <jesse@localhost> + Date: Thu Jul 24 18:38:14 2003 + + none + + rt.3.0.D165, C212, jesse, Wed Jul 23 18:06:41 2003, License tagger was tagging + Makefile, not Makefile.in. Reconfigured. + From: Jesse Vincent <jesse@localhost> + Date: Wed Jul 23 18:03:14 2003 + + none + + rt.3.0.D164, C211, jesse, Wed Jul 23 15:23:11 2003, Requestor searches had an + extra join that they didn't need + From: Jesse Vincent <jesse@localhost> + Date: Wed Jul 23 15:22:34 2003 + + none + + rt.3.0.D163, C207, leira, Tue Jul 22 03:10:34 2003, regression tests: use + $RT::WebPath and RT_LIB_PATH + From: Linda L. Julien <leira@starsong.org> + Date: Mon Jul 21 18:12:56 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D162, C210, jesse, Tue Jul 22 02:52:01 2003, A couple of fixes to + better deal with creation of 'blank' ticket requestors + From: Jesse Vincent <jesse@localhost> + Date: Tue Jul 22 02:50:09 2003 + + none + + rt.3.0.D161, C208, leira, Tue Jul 22 01:56:30 2003, #1651: URIs not escaped in + ticket display + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Jul 21 18:33:24 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D160, C209, leira, Tue Jul 22 01:54:49 2003, #1751: update second page + in Bulk update + From: Linda Julien <leira@hawthorn.local.> + Date: Mon Jul 21 20:54:02 2003 + Warning: the original change was in the 'awaiting_integration' state + + none + + rt.3.0.D159, C24, jesse, Fri Jul 18 18:59:13 2003, Certain ACL checks could + fail on postgres due to a marshalling bug + From: Jesse Vincent <jesse@localhost> + Date: Fri Jul 18 17:06:39 2003 + + none + + rt.3.0.D158, C206, jesse, Fri Jul 18 18:58:22 2003, Extended ACL edit routines + to make it easier to use generic routines in 3rd party apps + From: Jesse Vincent <jesse@localhost> + Date: Fri Jul 18 17:04:15 2003 + + none + + rt.3.0.D157, C205, jesse, Mon Jul 14 02:51:28 2003, Removing ancient cli code + that was accidentally added to the repository + From: Jesse Vincent <jesse@localhost> + Date: Sun Jul 13 23:47:51 2003 + + none + + rt.3.0.D156, C203, jesse, Sun Jul 13 22:35:44 2003, More updates to the + commandline client + From: Jesse Vincent <jesse@localhost> + Date: Sun Jul 13 19:32:10 2003 + + none + + rt.3.0.D155, C202, jesse, Sun Jul 13 21:33:58 2003, Initial commit of new + commandline client support code + From: Jesse Vincent <jesse@localhost> + Date: Sun Jul 13 18:33:29 2003 + + none + + rt.3.0.D154, C196, jesse, Sun Jul 13 18:06:09 2003, #3029 - better warning + message on improper perms on mail in + From: Jesse Vincent <jesse@localhost> + Date: Tue Jul 8 16:59:59 2003 + + none + + rt.3.0.D153, C195, jesse, Sun Jul 13 18:05:41 2003, #3042: Make max inline + body size configurable + From: Jesse Vincent <jesse@localhost> + Date: Tue Jul 8 16:55:28 2003 + + none rt.3.0.D152, C201, jesse, Sat Jul 12 02:41:34 2003, Bumping version to 3.0.4 From: Jesse Vincent <jesse@localhost> diff --git a/rt/Makefile b/rt/Makefile index 644722109..0895874fb 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -1,20 +1,19 @@ # BEGIN LICENSE BLOCK # -# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com> +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> # # (Except where explictly superceded by other copyright notices) # # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed -# from www.gnu.org +# from www.gnu.org. # # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # -# # Unless otherwise specified, all modifications, corrections or # extensions to this work which alter its source code become the # property of Best Practical Solutions, LLC when submitted for @@ -22,8 +21,6 @@ # # # END LICENSE BLOCK - - # # DO NOT HAND-EDIT the file named 'Makefile'. This file is autogenerated. # Have a look at "configure" and "Makefile.in" instead @@ -39,7 +36,7 @@ SITE_CONFIG_FILE = $(CONFIG_FILE_PATH)/RT_SiteConfig.pm RT_VERSION_MAJOR = 3 RT_VERSION_MINOR = 0 -RT_VERSION_PATCH = 4 +RT_VERSION_PATCH = 9 RT_VERSION = $(RT_VERSION_MAJOR).$(RT_VERSION_MINOR).$(RT_VERSION_PATCH) TAG = rt-$(RT_VERSION_MAJOR)-$(RT_VERSION_MINOR)-$(RT_VERSION_PATCH) @@ -101,8 +98,8 @@ RT_MODPERL_HANDLER = $(RT_BIN_PATH)/webmux.pl RT_FASTCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.fcgi # RT_WIN32_FASTCGI_HANDLER is the mason handler script for FastCGI RT_WIN32_FASTCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.svc -# RT's admin CLI -RT_CLI_ADMIN_BIN = $(RT_BIN_PATH)/rtadmin +# RT's CLI +RT_CLI_BIN = $(RT_BIN_PATH)/rt # RT's mail gateway RT_MAILGATE_BIN = $(RT_BIN_PATH)/rt-mailgate # RT's cron tool @@ -115,6 +112,7 @@ SETGID_BINARIES = $(DESTDIR)/$(RT_FASTCGI_HANDLER) \ BINARIES = $(DESTDIR)/$(RT_MODPERL_HANDLER) \ $(DESTDIR)/$(RT_MAILGATE_BIN) \ + $(DESTDIR)/$(RT_CLI_BIN) \ $(DESTDIR)/$(RT_CRON_BIN) \ $(SETGID_BINARIES) SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/ @@ -128,6 +126,7 @@ SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/ # DB_TYPE defines what sort of database RT trys to talk to # "mysql" is known to work. # "Pg" is known to work +# "Informix" is known to work DB_TYPE = mysql @@ -138,7 +137,8 @@ DB_TYPE = mysql # For mysql, you probably want 'root' # For Pg, you probably want 'postgres' -# For oracle, you want 'system' +# For Oracle, you want 'system' +# For Informix, you want 'informix' DB_DBA = root @@ -211,7 +211,7 @@ upgrade-instruct: @echo " $(RT_SBIN_PATH)/rt-setup-database --action insert --datafile etc/upgrade/<version>" -upgrade: dirs upgrade-noclobber upgrade-instruct +upgrade: config-install dirs files-install fixperms upgrade-instruct upgrade-noclobber: config-install libs-install html-install bin-install local-install doc-install fixperms @@ -312,13 +312,16 @@ config-install: test: $(PERL) -Ilib lib/t/00smoke.t -regression-nosetgid-quiet: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl +regression-install: config-install + $(PERL) -pi -e 's/Set\(\$$DatabaseName.*\);/Set\(\$$DatabaseName, "rt3regression"\);/' $(DESTDIR)/$(CONFIG_FILE) + +regression-nosetgid-quiet: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl $(PERL) sbin/regression_harness -regression-nosetgid: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl +regression-nosetgid: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl $(PERL) lib/t/02regression.t -regression: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods apachectl +regression: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms apachectl $(PERL) lib/t/02regression.t regression-quiet: @@ -397,7 +400,9 @@ bin-install: -cp -rp \ bin/rt-mailgate \ bin/mason_handler.fcgi \ + bin/mason_handler.scgi \ bin/mason_handler.svc \ + bin/rt \ bin/webmux.pl \ bin/rt-crontool \ $(DESTDIR)/$(RT_BIN_PATH) diff --git a/rt/Makefile.in b/rt/Makefile.in index 245ec5ed3..c3eabc634 100644 --- a/rt/Makefile.in +++ b/rt/Makefile.in @@ -1,20 +1,19 @@ # BEGIN LICENSE BLOCK # -# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com> +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> # # (Except where explictly superceded by other copyright notices) # # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed -# from www.gnu.org +# from www.gnu.org. # # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # -# # Unless otherwise specified, all modifications, corrections or # extensions to this work which alter its source code become the # property of Best Practical Solutions, LLC when submitted for @@ -22,8 +21,6 @@ # # # END LICENSE BLOCK - - # # DO NOT HAND-EDIT the file named 'Makefile'. This file is autogenerated. # Have a look at "configure" and "Makefile.in" instead @@ -101,8 +98,8 @@ RT_MODPERL_HANDLER = $(RT_BIN_PATH)/webmux.pl RT_FASTCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.fcgi # RT_WIN32_FASTCGI_HANDLER is the mason handler script for FastCGI RT_WIN32_FASTCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.svc -# RT's admin CLI -RT_CLI_ADMIN_BIN = $(RT_BIN_PATH)/rtadmin +# RT's CLI +RT_CLI_BIN = $(RT_BIN_PATH)/rt # RT's mail gateway RT_MAILGATE_BIN = $(RT_BIN_PATH)/rt-mailgate # RT's cron tool @@ -115,6 +112,7 @@ SETGID_BINARIES = $(DESTDIR)/$(RT_FASTCGI_HANDLER) \ BINARIES = $(DESTDIR)/$(RT_MODPERL_HANDLER) \ $(DESTDIR)/$(RT_MAILGATE_BIN) \ + $(DESTDIR)/$(RT_CLI_BIN) \ $(DESTDIR)/$(RT_CRON_BIN) \ $(SETGID_BINARIES) SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/ @@ -128,6 +126,7 @@ SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/ # DB_TYPE defines what sort of database RT trys to talk to # "mysql" is known to work. # "Pg" is known to work +# "Informix" is known to work DB_TYPE = @DB_TYPE@ @@ -138,7 +137,8 @@ DB_TYPE = @DB_TYPE@ # For mysql, you probably want 'root' # For Pg, you probably want 'postgres' -# For oracle, you want 'system' +# For Oracle, you want 'system' +# For Informix, you want 'informix' DB_DBA = @DB_DBA@ @@ -211,7 +211,7 @@ upgrade-instruct: @echo " $(RT_SBIN_PATH)/rt-setup-database --action insert --datafile etc/upgrade/<version>" -upgrade: dirs upgrade-noclobber upgrade-instruct +upgrade: config-install dirs files-install fixperms upgrade-instruct upgrade-noclobber: config-install libs-install html-install bin-install local-install doc-install fixperms @@ -312,13 +312,16 @@ config-install: test: $(PERL) -Ilib lib/t/00smoke.t -regression-nosetgid-quiet: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl +regression-install: config-install + $(PERL) -pi -e 's/Set\(\$$DatabaseName.*\);/Set\(\$$DatabaseName, "rt3regression"\);/' $(DESTDIR)/$(CONFIG_FILE) + +regression-nosetgid-quiet: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl $(PERL) sbin/regression_harness -regression-nosetgid: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl +regression-nosetgid: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl $(PERL) lib/t/02regression.t -regression: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods apachectl +regression: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms apachectl $(PERL) lib/t/02regression.t regression-quiet: @@ -397,7 +400,9 @@ bin-install: -cp -rp \ bin/rt-mailgate \ bin/mason_handler.fcgi \ + bin/mason_handler.scgi \ bin/mason_handler.svc \ + bin/rt \ bin/webmux.pl \ bin/rt-crontool \ $(DESTDIR)/$(RT_BIN_PATH) @@ -21,6 +21,7 @@ # # # END LICENSE BLOCK + RT is an enterprise-grade issue tracking system. It allows organizations to keep track of their to-do lists, who is working on which tasks, what's already been done, and when tasks were @@ -36,22 +37,22 @@ up and use. REQUIRED PACKAGES: ------------------ -o Perl 5.8.0 or later (http://www.perl.com). +o Perl 5.8.3 or later (http://www.perl.com). (If you intend to use the FastCGI or SpeedyCGI support, you need to make sure that perl has been built with support for setgid perl scripts.)` + Perl versions prior to 5.8.3 contain bugs that could result in data + corruption. We recommend strongly that you use 5.8.3 or newer. + Perl 5.6.1 is currently deprecated and will be officially desupported in a future release o A DB backend; MySQL is recommended ( http://www.mysql.com ) Currently supported: Mysql 4.0.13 or later. Postgres 7.2 or later. - - Mysql 3.23.46 or newer with support for InnoDB - is currently deprecated and will be officially - desupported in a future release. + Oracle 9iR2. o Apache version 1.3.x or 2.x (http://httpd.apache.org) with mod_perl -- (http://perl.apache.org ) @@ -119,7 +120,7 @@ http://www.bestpractical.com/rt perl sbin/rt-test-dependencies \ --with-<databasename> --with-<web-environment> - databasename is one of: mysql, postgres + databasename is one of: mysql, postgres, oracle web-environment is one of: fastcgi, modperl1, modperl2 3.2 If there are unsatisfied dependencies, install them by hand or run: @@ -151,6 +152,10 @@ http://www.bestpractical.com/rt 5b FOR UPGRADING: (Within the RT 3.0.x series) + + Read through the UPGRADING document included in this distribution. + It may contain important instructions for updating your database + As root, type: make upgrade (replace "make" with the local name for Make, if you need to) @@ -160,6 +165,14 @@ http://www.bestpractical.com/rt It may then instruct you to update your RT system database objects +5c FOR UPGRADING: (From RT 2.0.x) + + Download the RT2 to RT3 migration tools from: + + http://bestpractical.com/pub/rt/devel/rt2-to-rt3.tar.gz + + Follow the included instructions. + 6 Edit etc/RT_SiteConfig.pm in your RT installation directory, by specifying any values you need to change from the defaults in etc/RT_Config.pm @@ -192,31 +205,20 @@ Apache DocumentRoot /opt/rt3/share/html AddDefaultCharset UTF-8 - # this line applies to Apache2+mod_perl2 only + # these four lines apply to Apache2+mod_perl2 only: {{{ + PerlSetVar MasonArgsMethod CGI PerlModule Apache2 Apache::compat + RewriteEngine On + RewriteRule ^(.*)/$ $1/index.html + # }}} PerlModule Apache::DBI PerlRequire /opt/rt3/bin/webmux.pl - # this section applies to Apache 1 only <Location /> SetHandler perl-script PerlHandler RT::Mason </Location> - - # this section applies to Apache2+mod_perl2 only - <FilesMatch "\.html$"> - SetHandler perl-script - PerlHandler RT::Mason - </FilesMatch> - <LocationMatch "/Attachment/"> - SetHandler perl-script - PerlHandler RT::Mason - </LocationMatch> - <LocationMatch "/REST/"> - SetHandler perl-script - PerlHandler RT::Mason - </LocationMatch> </VirtualHost> diff --git a/rt/README.Oracle b/rt/README.Oracle new file mode 100644 index 000000000..41bec822c --- /dev/null +++ b/rt/README.Oracle @@ -0,0 +1,37 @@ +In order to install RT with Oracle, the database must first be +prepared. Ports of RT to other databases will automatically create +the RT schema. This is not done for Oracle because most sites wishing +to deploy RT on Oracle will have choose to make specific configuration +of the RT user, for example to select the appropriate tablespace or to +set up a resource profile. The RT user must have appropriate +privileges similar to the resource and connect roles and must have the +"query rewrite" system privilege. + Here is an example of commands to create an RT user called "RT" with +a password of "rt". + + create user rt identified by rt default tablespace users temporary + tablespace temp; + grant resource, connect, query rewrite to rt; + + +RT should not run its schema creation as the Oracle DBA; instead the +schema creation should be run as the RT user. To accomplish this set +the --with-rt-dba configuration parameter to the RT user, not to the +Oracle DBA. As an example, the following might be appropriate to +configure RT for the example.com Oracle database. + + ./configure --prefix /usr/local/rt --with-db-type=Oracle \ + --with-db-dba=rt --with-db-database=example.com \ + --with-db-rt-user=rt \ + --with-db-rt-pass=rt + + +As with all databases it is important to analyze the Schema and get +current statistics after any significant dataset change. Oracle's +cost-based optimizer can provide particularly bad performance when the +schema statistics are significantly inaccurate. To analyze the schema +of a user called rt, execute the following from withing Sqlplus. + + execute dbms_utility.analyze_schema( 'RT', 'estimate'); + + diff --git a/rt/UPGRADING b/rt/UPGRADING new file mode 100644 index 000000000..4306eb6cb --- /dev/null +++ b/rt/UPGRADING @@ -0,0 +1,64 @@ +UPGRADING + + +******* +WARNING +******* + + +Before making any changes to your database, always ensure that you have a +complete current backup. If you don't have a current backup, you could +accidentally damage your database and lose data or worse. + + + +Look for the + + +---------------------------------------------------------------------- + +3.0.7 +===== + +All Databases +------------- + +If you are upgrading from versions between 3.0.0 and 3.0.7, inclusive, +you might find improved performance by adding the following index to +your database: + +CREATE INDEX Links4 ON Links(Type,LocalBase); + + + +3.0.6 +===== + + +All Databases +------------- + +If you are upgrading from versions between 3.0.0 and 3.0.6, inclusive, +you might find improved performance by adding the following indices to +your database: + + CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); + CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); + + CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); + + + +Postgres +-------- + +If you have a Postgres database, the following changes to your +database can improve performance: + + ALTER TABLE groups rename instance to instance1; + ALTER TABLE groups add instance int; + UPDATE groups SET instance = instance1::text::int where btrim(instance1) <> ''; + ALTER TABLE groups drop column instance1; + + + diff --git a/rt/autom4te.cache/output.0 b/rt/autom4te.cache/output.0 index 51a8aaf63..3d27db94f 100644 --- a/rt/autom4te.cache/output.0 +++ b/rt/autom4te.cache/output.0 @@ -1,7 +1,7 @@ @%:@! /bin/sh @%:@ From configure.ac Revision: 1.1 . @%:@ Guess values for system-dependent variables and create Makefiles. -@%:@ Generated by GNU Autoconf 2.53 for RT 3.0.4. +@%:@ Generated by GNU Autoconf 2.53 for RT 3.0.9. @%:@ @%:@ Report bugs to <rt-3.0-bugs@fsck.com>. @%:@ @@ -257,8 +257,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='RT' PACKAGE_TARNAME='rt' -PACKAGE_VERSION='3.0.4' -PACKAGE_STRING='RT 3.0.4' +PACKAGE_VERSION='3.0.9' +PACKAGE_STRING='RT 3.0.9' PACKAGE_BUGREPORT='rt-3.0-bugs@fsck.com' ac_unique_file="lib/RT.pm.in" @@ -711,7 +711,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures RT 3.0.4 to adapt to many kinds of systems. +\`configure' configures RT 3.0.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -768,7 +768,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RT 3.0.4:";; + short | recursive ) echo "Configuration of RT 3.0.9:";; esac cat <<\_ACEOF @@ -786,8 +786,8 @@ Optional Packages: --with-bin-owner=OWNER user that will own rt binaries (default root) --with-libs-owner=OWNER user that will own RT libraries (default root) --with-libs-group=GROUP group that will own rt binaries (default bin) - --with-db-type=TYPE sort of database RT will use (default: mysql) (mysql - and Pg are valid) + --with-db-type=TYPE sort of database RT will use (default: mysql) + (mysql, Pg, Oracle and Informix are valid) --with-db-host=HOSTNAME FQDN of database server (default: localhost) --with-db-port=PORT port on which the database listens on --with-db-rt-host=HOSTNAME @@ -802,6 +802,7 @@ Optional Packages: password for database user (default: rt_pass) --with-web-user=USER user the web server runs as (default: www) --with-web-group=GROUP group the web server runs as (default: www) + --with-my-user-group set all users and groups to current user/group Some influential environment variables: PERL Perl interpreter command @@ -872,7 +873,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -RT configure 3.0.4 +RT configure 3.0.9 generated by GNU Autoconf 2.53 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 @@ -887,7 +888,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RT $as_me 3.0.4, which was +It was created by RT $as_me 3.0.9, which was generated by GNU Autoconf 2.53. Invocation command line was $ $0 $@ @@ -1171,7 +1172,7 @@ rt_version_major=3 rt_version_minor=0 -rt_version_patch=4 +rt_version_patch=9 test "x$rt_version_major" = 'x' && rt_version_major=0 test "x$rt_version_minor" = 'x' && rt_version_minor=0 @@ -1703,13 +1704,21 @@ if test "${with_db_type+set}" = set; then else DB_TYPE=mysql fi; -if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite'; then - { { echo "$as_me:$LINENO: error: Only Pg and mysql are valid db types" >&5 -echo "$as_me: error: Only Pg and mysql are valid db types" >&2;} +if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite' -a "$DB_TYPE" != 'Oracle' -a "$DB_TYPE" != 'Informix' ; then + { { echo "$as_me:$LINENO: error: Only Oracle, Informix, Pg and mysql are valid db types" >&5 +echo "$as_me: error: Only Oracle, Informix, Pg and mysql are valid db types" >&2;} { (exit 1); exit 1; }; } fi +if test "$DB_TYPE" = 'Oracle'; then + test "x$ORACLE_HOME" = 'x' && { { echo "$as_me:$LINENO: error: Please declare the ORACLE_HOME environment variable" >&5 +echo "$as_me: error: Please declare the ORACLE_HOME environment variable" >&2;} + { (exit 1); exit 1; }; } + ORACLE_ENV_PREF="\$ENV{'ORACLE_HOME'} = '$ORACLE_HOME';" +fi + + # Check whether --with-db-host or --without-db-host was given. if test "${with_db_host+set}" = set; then @@ -1800,6 +1809,19 @@ else fi; +my_group=$(groups|cut -f1 -d' ') + +# Check whether --with-my-user-group or --without-my-user-group was given. +if test "${with_my_user_group+set}" = set; then + withval="$with_my_user_group" + RTGROUP=$my_group + BIN_OWNER=$USER + LIBS_OWNER=$USER + LIBS_GROUP=$my_group + WEB_USER=$USER + WEB_GROUP=$my_group +fi; + RT_VERSION_MAJOR=${rt_version_major} @@ -1848,7 +1870,7 @@ RT_LOG_PATH=${exp_logfiledir} -ac_config_files="$ac_config_files sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/webmux.pl" +ac_config_files="$ac_config_files sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/rt bin/webmux.pl" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -2206,7 +2228,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by RT $as_me 3.0.4, which was +This file was extended by RT $as_me 3.0.9, which was generated by GNU Autoconf 2.53. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -2260,7 +2282,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -RT config.status 3.0.4 +RT config.status 3.0.9 configured by $0, generated by GNU Autoconf 2.53, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -2363,6 +2385,7 @@ do "bin/rt-commit-handler" ) CONFIG_FILES="$CONFIG_FILES bin/rt-commit-handler" ;; "bin/rt-crontool" ) CONFIG_FILES="$CONFIG_FILES bin/rt-crontool" ;; "bin/rt-mailgate" ) CONFIG_FILES="$CONFIG_FILES bin/rt-mailgate" ;; + "bin/rt" ) CONFIG_FILES="$CONFIG_FILES bin/rt" ;; "bin/webmux.pl" ) CONFIG_FILES="$CONFIG_FILES bin/webmux.pl" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} @@ -2487,6 +2510,7 @@ s,@BIN_OWNER@,$BIN_OWNER,;t t s,@LIBS_OWNER@,$LIBS_OWNER,;t t s,@LIBS_GROUP@,$LIBS_GROUP,;t t s,@DB_TYPE@,$DB_TYPE,;t t +s,@ORACLE_ENV_PREF@,$ORACLE_ENV_PREF,;t t s,@DB_HOST@,$DB_HOST,;t t s,@DB_PORT@,$DB_PORT,;t t s,@DB_RT_HOST@,$DB_RT_HOST,;t t diff --git a/rt/autom4te.cache/traces.0 b/rt/autom4te.cache/traces.0 index 962f400e7..f13276211 100644 --- a/rt/autom4te.cache/traces.0 +++ b/rt/autom4te.cache/traces.0 @@ -52,7 +52,7 @@ m4trace:configure.ac:9: -1- AC_SUBST([ECHO_T]) m4trace:configure.ac:9: -1- AC_SUBST([LIBS]) m4trace:configure.ac:14: -1- AC_SUBST([rt_version_major], [3]) m4trace:configure.ac:16: -1- AC_SUBST([rt_version_minor], [0]) -m4trace:configure.ac:18: -1- AC_SUBST([rt_version_patch], [4]) +m4trace:configure.ac:18: -1- AC_SUBST([rt_version_patch], [9]) m4trace:configure.ac:24: -1- AC_PROG_INSTALL m4trace:configure.ac:24: -1- AC_SUBST([INSTALL_PROGRAM]) m4trace:configure.ac:24: -1- AC_SUBST([INSTALL_SCRIPT]) @@ -104,38 +104,39 @@ m4trace:configure.ac:57: -1- AC_SUBST([BIN_OWNER]) m4trace:configure.ac:65: -1- AC_SUBST([LIBS_OWNER]) m4trace:configure.ac:73: -1- AC_SUBST([LIBS_GROUP]) m4trace:configure.ac:84: -1- AC_SUBST([DB_TYPE]) -m4trace:configure.ac:92: -1- AC_SUBST([DB_HOST]) -m4trace:configure.ac:100: -1- AC_SUBST([DB_PORT]) -m4trace:configure.ac:108: -1- AC_SUBST([DB_RT_HOST]) -m4trace:configure.ac:116: -1- AC_SUBST([DB_DBA]) -m4trace:configure.ac:124: -1- AC_SUBST([DB_DATABASE]) -m4trace:configure.ac:132: -1- AC_SUBST([DB_RT_USER]) -m4trace:configure.ac:140: -1- AC_SUBST([DB_RT_PASS]) -m4trace:configure.ac:148: -1- AC_SUBST([WEB_USER]) -m4trace:configure.ac:156: -1- AC_SUBST([WEB_GROUP]) -m4trace:configure.ac:163: -1- AC_SUBST([RT_VERSION_MAJOR], [${rt_version_major}]) -m4trace:configure.ac:164: -1- AC_SUBST([RT_VERSION_MINOR], [${rt_version_minor}]) -m4trace:configure.ac:165: -1- AC_SUBST([RT_VERSION_PATCH], [${rt_version_patch}]) -m4trace:configure.ac:168: -1- AC_SUBST([RT_PATH], [${exp_prefix}]) -m4trace:configure.ac:169: -1- AC_SUBST([RT_DOC_PATH], [${exp_manualdir}]) -m4trace:configure.ac:170: -1- AC_SUBST([RT_LOCAL_PATH], [${exp_customdir}]) -m4trace:configure.ac:171: -1- AC_SUBST([RT_LIB_PATH], [${exp_libdir}]) -m4trace:configure.ac:172: -1- AC_SUBST([RT_ETC_PATH], [${exp_sysconfdir}]) -m4trace:configure.ac:173: -1- AC_SUBST([CONFIG_FILE_PATH], [${exp_sysconfdir}]) -m4trace:configure.ac:174: -1- AC_SUBST([RT_BIN_PATH], [${exp_bindir}]) -m4trace:configure.ac:175: -1- AC_SUBST([RT_SBIN_PATH], [${exp_sbindir}]) -m4trace:configure.ac:176: -1- AC_SUBST([RT_VAR_PATH], [${exp_localstatedir}]) -m4trace:configure.ac:177: -1- AC_SUBST([RT_MAN_PATH], [${exp_mandir}]) -m4trace:configure.ac:178: -1- AC_SUBST([MASON_DATA_PATH], [${exp_masonstatedir}]) -m4trace:configure.ac:179: -1- AC_SUBST([MASON_SESSION_PATH], [${exp_sessionstatedir}]) -m4trace:configure.ac:180: -1- AC_SUBST([MASON_HTML_PATH], [${exp_htmldir}]) -m4trace:configure.ac:181: -1- AC_SUBST([LOCAL_ETC_PATH], [${exp_custometcdir}]) -m4trace:configure.ac:182: -1- AC_SUBST([MASON_LOCAL_HTML_PATH], [${exp_customhtmldir}]) -m4trace:configure.ac:183: -1- AC_SUBST([LOCAL_LEXICON_PATH], [${exp_customlexdir}]) -m4trace:configure.ac:184: -1- AC_SUBST([LOCAL_LIB_PATH], [${exp_customlibdir}]) -m4trace:configure.ac:185: -1- AC_SUBST([DESTDIR], [${exp_prefix}]) -m4trace:configure.ac:186: -1- AC_SUBST([RT_LOG_PATH], [${exp_logfiledir}]) -m4trace:configure.ac:208: -1- AC_CONFIG_FILES([ +m4trace:configure.ac:91: -1- AC_SUBST([ORACLE_ENV_PREF]) +m4trace:configure.ac:99: -1- AC_SUBST([DB_HOST]) +m4trace:configure.ac:107: -1- AC_SUBST([DB_PORT]) +m4trace:configure.ac:115: -1- AC_SUBST([DB_RT_HOST]) +m4trace:configure.ac:123: -1- AC_SUBST([DB_DBA]) +m4trace:configure.ac:131: -1- AC_SUBST([DB_DATABASE]) +m4trace:configure.ac:139: -1- AC_SUBST([DB_RT_USER]) +m4trace:configure.ac:147: -1- AC_SUBST([DB_RT_PASS]) +m4trace:configure.ac:155: -1- AC_SUBST([WEB_USER]) +m4trace:configure.ac:163: -1- AC_SUBST([WEB_GROUP]) +m4trace:configure.ac:182: -1- AC_SUBST([RT_VERSION_MAJOR], [${rt_version_major}]) +m4trace:configure.ac:183: -1- AC_SUBST([RT_VERSION_MINOR], [${rt_version_minor}]) +m4trace:configure.ac:184: -1- AC_SUBST([RT_VERSION_PATCH], [${rt_version_patch}]) +m4trace:configure.ac:187: -1- AC_SUBST([RT_PATH], [${exp_prefix}]) +m4trace:configure.ac:188: -1- AC_SUBST([RT_DOC_PATH], [${exp_manualdir}]) +m4trace:configure.ac:189: -1- AC_SUBST([RT_LOCAL_PATH], [${exp_customdir}]) +m4trace:configure.ac:190: -1- AC_SUBST([RT_LIB_PATH], [${exp_libdir}]) +m4trace:configure.ac:191: -1- AC_SUBST([RT_ETC_PATH], [${exp_sysconfdir}]) +m4trace:configure.ac:192: -1- AC_SUBST([CONFIG_FILE_PATH], [${exp_sysconfdir}]) +m4trace:configure.ac:193: -1- AC_SUBST([RT_BIN_PATH], [${exp_bindir}]) +m4trace:configure.ac:194: -1- AC_SUBST([RT_SBIN_PATH], [${exp_sbindir}]) +m4trace:configure.ac:195: -1- AC_SUBST([RT_VAR_PATH], [${exp_localstatedir}]) +m4trace:configure.ac:196: -1- AC_SUBST([RT_MAN_PATH], [${exp_mandir}]) +m4trace:configure.ac:197: -1- AC_SUBST([MASON_DATA_PATH], [${exp_masonstatedir}]) +m4trace:configure.ac:198: -1- AC_SUBST([MASON_SESSION_PATH], [${exp_sessionstatedir}]) +m4trace:configure.ac:199: -1- AC_SUBST([MASON_HTML_PATH], [${exp_htmldir}]) +m4trace:configure.ac:200: -1- AC_SUBST([LOCAL_ETC_PATH], [${exp_custometcdir}]) +m4trace:configure.ac:201: -1- AC_SUBST([MASON_LOCAL_HTML_PATH], [${exp_customhtmldir}]) +m4trace:configure.ac:202: -1- AC_SUBST([LOCAL_LEXICON_PATH], [${exp_customlexdir}]) +m4trace:configure.ac:203: -1- AC_SUBST([LOCAL_LIB_PATH], [${exp_customlibdir}]) +m4trace:configure.ac:204: -1- AC_SUBST([DESTDIR], [${exp_prefix}]) +m4trace:configure.ac:205: -1- AC_SUBST([RT_LOG_PATH], [${exp_logfiledir}]) +m4trace:configure.ac:228: -1- AC_CONFIG_FILES([ sbin/rt-setup-database sbin/rt-test-dependencies Makefile @@ -152,5 +153,6 @@ m4trace:configure.ac:208: -1- AC_CONFIG_FILES([ bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate + bin/rt bin/webmux.pl ]) diff --git a/rt/bin/mason_handler.fcgi b/rt/bin/mason_handler.fcgi index 431eccbd3..93d1f8855 100755 --- a/rt/bin/mason_handler.fcgi +++ b/rt/bin/mason_handler.fcgi @@ -27,7 +27,7 @@ use strict; use File::Basename; require ('/opt/rt3/bin/webmux.pl'); -my $h = &RT::Interface::Web::NewCGIHandler(); +my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); # Enter CGI::Fast mode, which should also work as a vanilla CGI script. require CGI::Fast; @@ -44,11 +44,25 @@ while ( my $cgi = CGI::Fast->new ) { $ENV{'ENV'} = '' if defined $ENV{'ENV'}; $ENV{'IFS'} = '' if defined $ENV{'IFS'}; - unless ($h->interp->comp_exists($cgi->path_info)) { - $cgi->path_info($cgi->path_info . "/index.html"); + RT::ConnectToDatabase(); + + if ( ( !$h->interp->comp_exists( $cgi->path_info ) ) + && ( $h->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { + $cgi->path_info( $cgi->path_info . "/index.html" ); + } + + eval { $h->handle_cgi_object($cgi); }; + if ($@) { + $RT::Logger->crit($@); + } + + + if ($RT::Handle->TransactionDepth) { + $RT::Handle->ForceRollback; + $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") ; } - $h->handle_cgi_object($cgi); - # _should_ always be tied + + } 1; diff --git a/rt/bin/mason_handler.fcgi.in b/rt/bin/mason_handler.fcgi.in index e932bfc29..a009663b9 100644 --- a/rt/bin/mason_handler.fcgi.in +++ b/rt/bin/mason_handler.fcgi.in @@ -27,7 +27,7 @@ use strict; use File::Basename; require ('@RT_BIN_PATH@/webmux.pl'); -my $h = &RT::Interface::Web::NewCGIHandler(); +my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); # Enter CGI::Fast mode, which should also work as a vanilla CGI script. require CGI::Fast; @@ -44,11 +44,25 @@ while ( my $cgi = CGI::Fast->new ) { $ENV{'ENV'} = '' if defined $ENV{'ENV'}; $ENV{'IFS'} = '' if defined $ENV{'IFS'}; - unless ($h->interp->comp_exists($cgi->path_info)) { - $cgi->path_info($cgi->path_info . "/index.html"); + RT::ConnectToDatabase(); + + if ( ( !$h->interp->comp_exists( $cgi->path_info ) ) + && ( $h->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { + $cgi->path_info( $cgi->path_info . "/index.html" ); + } + + eval { $h->handle_cgi_object($cgi); }; + if ($@) { + $RT::Logger->crit($@); + } + + + if ($RT::Handle->TransactionDepth) { + $RT::Handle->ForceRollback; + $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") ; } - $h->handle_cgi_object($cgi); - # _should_ always be tied + + } 1; diff --git a/rt/bin/mason_handler.scgi b/rt/bin/mason_handler.scgi index 8e1135c2f..7774189ee 100755 --- a/rt/bin/mason_handler.scgi +++ b/rt/bin/mason_handler.scgi @@ -26,16 +26,18 @@ use strict; require ('/opt/rt3/bin/webmux.pl'); -my $h = &RT::Interface::Web::NewCGIHandler(); +my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); require CGI; RT::Init(); my $cgi = CGI->new; -unless ($h->interp->comp_exists($cgi->path_info)) { - $cgi->path_info($cgi->path_info . "/index.html"); +if ( ( !$h->interp->comp_exists( $cgi->path_info ) ) + && ( $h->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { + $cgi->path_info( $cgi->path_info . "/index.html" ); } + $h->handle_cgi_object($cgi); 1; diff --git a/rt/bin/mason_handler.scgi.in b/rt/bin/mason_handler.scgi.in index 37d8380c2..614d4d47a 100644 --- a/rt/bin/mason_handler.scgi.in +++ b/rt/bin/mason_handler.scgi.in @@ -26,16 +26,18 @@ use strict; require ('@RT_BIN_PATH@/webmux.pl'); -my $h = &RT::Interface::Web::NewCGIHandler(); +my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); require CGI; RT::Init(); my $cgi = CGI->new; -unless ($h->interp->comp_exists($cgi->path_info)) { - $cgi->path_info($cgi->path_info . "/index.html"); +if ( ( !$h->interp->comp_exists( $cgi->path_info ) ) + && ( $h->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { + $cgi->path_info( $cgi->path_info . "/index.html" ); } + $h->handle_cgi_object($cgi); 1; diff --git a/rt/bin/mason_handler.svc b/rt/bin/mason_handler.svc index e6d83784c..c05d21e69 100644 --- a/rt/bin/mason_handler.svc +++ b/rt/bin/mason_handler.svc @@ -197,7 +197,7 @@ BEGIN { warn "Begin listening on $ENV{'FCGI_SOCKET_PATH'}\n"; require CGI::Fast; -my $h = &RT::Interface::Web::NewCGIHandler(); +my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); RT::Init(); diff --git a/rt/bin/mason_handler.svc.in b/rt/bin/mason_handler.svc.in index cc12c0ef0..0ba1f51b5 100644 --- a/rt/bin/mason_handler.svc.in +++ b/rt/bin/mason_handler.svc.in @@ -197,7 +197,7 @@ BEGIN { warn "Begin listening on $ENV{'FCGI_SOCKET_PATH'}\n"; require CGI::Fast; -my $h = &RT::Interface::Web::NewCGIHandler(); +my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); RT::Init(); @@ -1,1391 +1,1816 @@ -#!!!PERL!! -w -# -# $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/rt,v 1.1 2002-08-12 06:17:07 ivan Exp $ -# RT is (c) 1996-2001 Jesse Vincent <jesse@bestpractical.com> +#!/usr/bin/perl -w +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK use strict; -use Carp; -use Getopt::Long; -use lib "!!RT_LIB_PATH!!"; -use lib "!!RT_ETC_PATH!!"; +# This program is intentionally written to have as few non-core module +# dependencies as possible. It should stay that way. + +use Cwd; +use LWP; +use HTTP::Request::Common; + +# We derive configuration information from hardwired defaults, dotfiles, +# and the RT* environment variables (in increasing order of precedence). +# Session information is stored in ~/.rt_sessions. + +my $VERSION = 0.02; +my $HOME = eval{(getpwuid($<))[7]} + || $ENV{HOME} || $ENV{LOGDIR} || $ENV{HOMEPATH} + || "."; +my %config = ( + ( + debug => 0, + user => eval{(getpwuid($<))[0]} || $ENV{USER} || $ENV{USERNAME}, + passwd => undef, + server => 'http://localhost/rt/', + ), + config_from_file($ENV{RTCONFIG} || ".rtrc"), + config_from_env() +); +my $session = new Session("$HOME/.rt_sessions"); +my $REST = "$config{server}/REST/1.0"; + +sub whine; +sub DEBUG { warn @_ if $config{debug} >= shift } + +# These regexes are used by command handlers to parse arguments. +# (XXX: Ask Autrijus how i18n changes these definitions.) + +my $name = '[\w.-]+'; +my $field = '[a-zA-Z][a-zA-Z0-9_-]*'; +my $label = '[a-zA-Z0-9@_.+-]+'; +my $labels = "(?:$label,)*$label"; +my $idlist = '(?:(?:\d+-)?\d+,)*(?:\d+-)?\d+'; + +# Our command line looks like this: +# +# rt <action> [options] [arguments] +# +# We'll parse just enough of it to decide upon an action to perform, and +# leave the rest to per-action handlers to interpret appropriately. + +my %handlers = ( +# handler => [ ...aliases... ], + version => ["version", "ver"], + logout => ["logout"], + help => ["help", "man"], + show => ["show", "cat"], + edit => ["create", "edit", "new", "ed"], + list => ["search", "list", "ls"], + comment => ["comment", "correspond"], + link => ["link", "ln"], + merge => ["merge"], + grant => ["grant", "revoke"], +); + +# Once we find and call an appropriate handler, we're done. + +my (%actions, $action); +foreach my $fn (keys %handlers) { + foreach my $alias (@{ $handlers{$fn} }) { + $actions{$alias} = \&{"$fn"}; + } +} +if (@ARGV && exists $actions{$ARGV[0]}) { + $action = shift @ARGV; +} +$actions{$action || "help"}->($action || ()); +exit; -use RT::Interface::CLI qw(CleanEnv LoadConfig DBConnect - GetCurrentUser GetMessageContent); +# Handler functions. +# ------------------ +# +# The following subs are handlers for each entry in %actions. -#Clean out all the nasties from the environment -CleanEnv(); +sub version { + print "rt $VERSION\n"; +} -#Load etc/config.pm and drop privs -LoadConfig(); +sub logout { + submit("$REST/logout") if defined $session->cookie; +} -#Connect to the database and get RT::SystemUser and RT::Nobody loaded -DBConnect(); +sub help { + my ($action, $type) = @_; + my (%help, $key); -#Drop setgid permissions -RT::DropSetGIDPermissions(); + # What help topics do we know about? + local $/ = undef; + foreach my $item (@{ Form::parse(<DATA>) }) { + my $title = $item->[2]{Title}; + my @titles = ref $title eq 'ARRAY' ? @$title : $title; -#Get the current user all loaded -my $CurrentUser = GetCurrentUser(); + foreach $title (grep $_, @titles) { + $help{$title} = $item->[2]{Text}; + } + } -unless ($CurrentUser->Id) { - print "No RT user found. Please consult your RT administrator.\n"; - exit(1); + # What does the user want help with? + undef $action if ($action && $actions{$action} eq \&help); + unless ($action || $type) { + # If we don't know, we'll look for clues in @ARGV. + foreach (@ARGV) { + if (exists $help{$_}) { $key = $_; last; } + } + unless ($key) { + # Tolerate possibly plural words. + foreach (@ARGV) { + if ($_ =~ s/s$// && exists $help{$_}) { $key = $_; last; } + } + } + } + + if ($type && $action) { + $key = "$type.$action"; + } + $key ||= $type || $action || "introduction"; + + # Find a suitable topic to display. + while (!exists $help{$key}) { + if ($type && $action) { + if ($key eq "$type.$action") { $key = $action; } + elsif ($key eq $action) { $key = $type; } + else { $key = "introduction"; } + } + else { + $key = "introduction"; + } + } + + print STDERR $help{$key}, "\n\n"; } +# Displays a list of objects that match some specified condition. -# {{{ commandline flags - -my ( @id, - @limit_queue, - @limit_status, - @limit_owner, - @limit_priority, - @limit_final_priority, - @limit_requestor, - @limit_subject, - @limit_body, - @limit_created, - @limit_resolved, - @limit_lastupdated, - @limit_dependson, - @limit_dependedonby, - @limit_memberof, - @limit_hasmember, - @limit_refersto, - @limit_referredtoby, - @limit_keyword, - - @limit_due, - @limit_starts, - @limit_started, - $limit_first, - $limit_rows, - $history, - $summary, - $create, - @requestors, - @cc, - @admincc, - $status, - $subject, - $owner, - $steal, - $queue, - $time_left, - $priority, - $final_priority, - $due, - $starts, - $started, - $contacted, - $comment, - $reply, - $source, - $edit, - @dependson, - @memberof, - @refersto, - $mergeinto, - @keywords, - $time_taken, - $verbose, - $debug, - $help, - $version); - -# }}} - -# Set defaults for cli args - -$edit = 1; # Assume the user wants to edit replies and comments - # unless they specify --noedit - -# {{{ args - -my @args =("id=s" => \@id, - "limit-queue=s" => \@limit_queue, - "limit-status=s" => \@limit_status, - "limit-owner=s" => \@limit_owner, - "limit-priority=s" => \@limit_priority, - "limit-final-priority=s" => \@limit_final_priority, - "limit-requestor=s" => \@limit_requestor, - "limit-subject=s" => \@limit_subject, - "limit-body=s", \@limit_body, - "limit-created=s" => \@limit_created, - "limit-due=s" => \@limit_due, - "limit-last-updated=s" => \@limit_lastupdated, - "limit-keyword=s" => \@limit_keyword, - - "limit-member-of=s" => \@limit_memberof, - "limit-has-member=s" => \@limit_hasmember, - "limit-depended-on-by=s" => \@limit_dependedonby, - "limit-depends-on=s" => \@limit_dependson, - "limit-referred-to-by=s" => \@limit_referredtoby, - "limit-refers-to=s" => \@limit_refersto, - - "limit-starts=s" => \@limit_starts, - "limit-started=s" => \@limit_started, - "limit-first=i" => \$limit_first, - "limit-rows=i" => \$limit_rows, - "history|show" => \$history, - "summary:s" => \$summary, - "create" => \$create, - "keywords=s" => \@keywords, - "requestor|requestors=s" => \@requestors, - "cc=s" => \@cc, - "admincc=s" => \@admincc, - "status=s" => \$status, - "subject=s" => \$subject, - "owner=s" => \$owner, - "steal" => \$steal, - "queue=s" => \$queue, - - - "priority=i" => \$priority, - "final-priority=i" => \$final_priority, - "due=s" => \$due, - "starts=s" => \$starts, - "started=s" => \$started, - "contacted=s" => \$contacted, - "comment", \$comment, - "reply|respond", \$reply, - "source=s" => \$source, - "edit!" => \$edit, - "depends-on=s" => \@dependson, - "member-of=s" => \@memberof, - "merge-into=s" => \$mergeinto, - "refers-to=s" => \@refersto, - "time-left=i" => \$time_left, - "time-taken=i" => \$time_taken, - "verbose+" => \$verbose, - "debug" => \$debug, - "version" => \$version, - "help|h|usage" => \$help - ); - -# }}} - - - -GetOptions(@args); - -print join(':',@keywords); -# {{{ If they want it, print a usage message and get out - -if ($help) { - - -print <<EOUSAGE; - -Limit the set of records returned: - ---id=[first][-][last] - Specify a single ticket, a range, or to start with (n-) or end with (-n) -a specific ticket. - - --limit-queue=<queue> - --limit-status=[!](new|open|stalled|resolved) - - --limit-owner=[!]<userid> - --limit-priority=[starts][-][ends] - --limit-final-priority=[starts][-][ends] - starts is less than ends - --limit-requestor=[!]<userid>|<email> - --limit-subject=[!]<text> - --limit-body=[!]<text> - --limit-keyword=[!]<select>/<keyword> - - Links - --limit-member-of=<ticketid> - --limit-has-member=<ticketid> - --limit-refers-to=<ticketid> - --limit-referred-to-by=<ticketid> - --limit-depends-on=<ticketid> - --limit-depended-on-by=<ticketid> +sub list { + my ($q, $type, %data, $orderby); + my $bad = 0; + while (@ARGV) { + $_ = shift @ARGV; - Dates - --limit-created=[starts][-][ends] - --limit-due=[starts][-][ends] - --limit-starts=[starts][-][ends] - --limit-started=[starts][-][ends] - --limit-resolved=[starts][-][ends] - --limit-last-updated=[starts][-][ends] - starts and ends are dates. starts can not be less than ends + if (/^-t$/) { + $bad = 1, last unless defined($type = get_type_argument()); + } + elsif (/^-S$/) { + $bad = 1, last unless get_var_argument(\%data); + } + elsif (/^-o$/) { + $orderby = shift @ARGV; + } + elsif (/^-([isl])$/) { + $data{format} = $1; + } + elsif (/^-f$/) { + if ($ARGV[0] !~ /^(?:(?:$field,)*$field)$/) { + whine "No valid field list in '-f $ARGV[0]'."; + $bad = 1; last; + } + $data{fields} = shift @ARGV; + } + elsif (!defined $q && !/^-/) { + $q = $_; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } - --limit-first=<first row returned> - --limit-rows=<row count> + $type ||= "ticket"; + unless ($type && defined $q) { + my $item = $type ? "query string" : "object type"; + whine "No $item specified."; + $bad = 1; + } + return help("list", $type) if $bad; - --history | --show - show a history of the tickets found - + my $r = submit("$REST/search/$type", { query => $q, %data, orderby => $orderby || "" }); + print $r->content; +} - --summary [format-string] - show a listing-style summary of the tickets found. If format string - is ommitted, uses \$RT_SUMMARY_FORMAT or an internal default - +# Displays selected information about a single object. - #TODO: doc summary - format: <atom>%<format> - atom: <name><size> - size: <integer> - name: (grep for # {{{ attribs for the array of ok values) +sub show { + my ($type, @objects, %data); + my $slurped = 0; + my $bad = 0; + while (@ARGV) { + $_ = shift @ARGV; - --create - create a new ticket. Any attributes that you can modify on an existing ticket - can also be used for ticket creation. + if (/^-t$/) { + $bad = 1, last unless defined($type = get_type_argument()); + } + elsif (/^-S$/) { + $bad = 1, last unless get_var_argument(\%data); + } + elsif (/^-([isl])$/) { + $data{format} = $1; + } + elsif (/^-$/ && !$slurped) { + chomp(my @lines = <STDIN>); + foreach (@lines) { + unless (is_object_spec($_, $type)) { + whine "Invalid object on STDIN: '$_'."; + $bad = 1; last; + } + push @objects, $_; + } + $slurped = 1; + } + elsif (/^-f$/) { + if ($ARGV[0] !~ /^(?:(?:$field,)*$field)$/) { + whine "No valid field list in '-f $ARGV[0]'."; + $bad = 1; last; + } + $data{fields} = shift @ARGV; + } + elsif (my $spec = is_object_spec($_, $type)) { + push @objects, $spec; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } + unless (@objects) { + whine "No objects specified."; + $bad = 1; + } + return help("show", $type) if $bad; + my $r = submit("$REST/show", { id => \@objects, %data }); + print $r->content; +} -Attributes - Basics - --status=<new|open|stalled|resolved|dead> - sets status - --subject=<subject> - sets subject - --owner=<userid> - set owner to - --steal - Become the owner, even if someone else owns the ticket - --queue=<queueid> - set queue to - - --priority=<int> - - --final-priority=<int> +# To create a new object, we ask the server for a form with the defaults +# filled in, allow the user to edit it, and send the form back. +# +# To edit an object, we must ask the server for a form representing that +# object, make changes requested by the user (either on the command line +# or interactively via $EDITOR), and send the form back. + +sub edit { + my ($action) = @_; + my (%data, $type, @objects); + my ($cl, $text, $edit, $input, $output); + + use vars qw(%set %add %del); + %set = %add = %del = (); + my $slurped = 0; + my $bad = 0; + + while (@ARGV) { + $_ = shift @ARGV; + + if (/^-e$/) { $edit = 1 } + elsif (/^-i$/) { $input = 1 } + elsif (/^-o$/) { $output = 1 } + elsif (/^-t$/) { + $bad = 1, last unless defined($type = get_type_argument()); + } + elsif (/^-S$/) { + $bad = 1, last unless get_var_argument(\%data); + } + elsif (/^-$/ && !($slurped || $input)) { + chomp(my @lines = <STDIN>); + foreach (@lines) { + unless (is_object_spec($_, $type)) { + whine "Invalid object on STDIN: '$_'."; + $bad = 1; last; + } + push @objects, $_; + } + $slurped = 1; + } + elsif (/^set$/i) { + my $vars = 0; + + while (@ARGV && $ARGV[0] =~ /^($field)([+-]?=)(.*)$/) { + my ($key, $op, $val) = ($1, $2, $3); + my $hash = ($op eq '=') ? \%set : ($op =~ /^\+/) ? \%add : \%del; + + vpush($hash, lc $key, $val); + shift @ARGV; + $vars++; + } + unless ($vars) { + whine "No variables to set."; + $bad = 1; last; + } + $cl = $vars; + } + elsif (/^(?:add|del)$/i) { + my $vars = 0; + my $hash = ($_ eq "add") ? \%add : \%del; + + while (@ARGV && $ARGV[0] =~ /^($field)=(.*)$/) { + my ($key, $val) = ($1, $2); + + vpush($hash, lc $key, $val); + shift @ARGV; + $vars++; + } + unless ($vars) { + whine "No variables to set."; + $bad = 1; last; + } + $cl = $vars; + } + elsif (my $spec = is_object_spec($_, $type)) { + push @objects, $spec; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } - Watchers - --requestors=[+|-]<userid|email address> - add or remove this user as a ticket requestor - --cc=[+|-]<userid|email address> - add or remove this user as a ticket cc - --admincc=[+|-]<userid|email address> - add or remove this user as a ticket admincc + if ($action =~ /^ed(?:it)?$/) { + unless (@objects) { + whine "No objects specified."; + $bad = 1; + } + } + else { + if (@objects) { + whine "You shouldn't specify objects as arguments to $action."; + $bad = 1; + } + unless ($type) { + whine "What type of object do you want to create?"; + $bad = 1; + } + @objects = ("$type/new"); + } + return help($action, $type) if $bad; - (When creating tickets, just leave off the + or - ) + # We need a form to make changes to. We usually ask the server for + # one, but we can avoid that if we are fed one on STDIN, or if the + # user doesn't want to edit the form by hand, and the command line + # specifies only simple variable assignments. - Keywords - --keywords[+|-]<keyword_select>/<keyword> - Add or remove a keyword. + if ($input) { + local $/ = undef; + $text = <STDIN>; + } + elsif ($edit || %add || %del || !$cl) { + my $r = submit("$REST/show", { id => \@objects, format => 'l' }); + $text = $r->content; + } + # If any changes were specified on the command line, apply them. + if ($cl) { + if ($text) { + # We're updating forms from the server. + my $forms = Form::parse($text); + + foreach my $form (@$forms) { + my ($c, $o, $k, $e) = @$form; + my ($key, $val); + + next if ($e || !@$o); + + local %add = %add; + local %del = %del; + local %set = %set; + + # Make changes to existing fields. + foreach $key (@$o) { + if (exists $add{lc $key}) { + $val = delete $add{lc $key}; + vpush($k, $key, $val); + $k->{$key} = vsplit($k->{$key}) if $val =~ /[,\n]/; + } + if (exists $del{lc $key}) { + $val = delete $del{lc $key}; + my %val = map {$_=>1} @{ vsplit($val) }; + $k->{$key} = vsplit($k->{$key}); + @{$k->{$key}} = grep {!exists $val{$_}} @{$k->{$key}}; + } + if (exists $set{lc $key}) { + $k->{$key} = delete $set{lc $key}; + } + } + + # Then update the others. + foreach $key (keys %set) { vpush($k, $key, $set{$key}) } + foreach $key (keys %add) { + vpush($k, $key, $add{$key}); + $k->{$key} = vsplit($k->{$key}); + } + push @$o, (keys %add, keys %set); + } + + $text = Form::compose($forms); + } + else { + # We're rolling our own set of forms. + my @forms; + foreach (@objects) { + my ($type, $ids, $args) = + m{^($name)/($idlist|$labels)(?:(/.*))?$}o; + + $args ||= ""; + foreach my $obj (expand_list($ids)) { + my %set = (%set, id => "$type/$obj$args"); + push @forms, ["", [keys %set], \%set]; + } + } + $text = Form::compose(\@forms); + } + } + if ($output) { + print $text; + exit; + } - Dates - --due=<date> - --starts=<date> - --started=<date> - --contacted=<date> + my $synerr = 0; - --time-left=<int> - - --time-taken=<int> +EDIT: + # We'll let the user edit the form before sending it to the server, + # unless we have enough information to submit it non-interactively. + if ($edit || (!$input && !$cl)) { + my $newtext = vi($text); + # We won't resubmit a bad form unless it was changed. + $text = ($synerr && $newtext eq $text) ? undef : $newtext; + } + if ($text) { + my $r = submit("$REST/edit", {content => $text, %data}); + if ($r->code == 409) { + # If we submitted a bad form, we'll give the user a chance + # to correct it and resubmit. + if ($edit || (!$input && !$cl)) { + $text = $r->content; + $synerr = 1; + goto EDIT; + } + else { + print $r->content; + exit -1; + } + } + print $r->content; + } +} - Link related manipulation: +# We roll "comment" and "correspond" into the same handler. - --depends-on=[+|-]<ticketid> - --member-of=[+|-]<ticketid> - --refers-to=[+|-]<ticketid> - --merge-into=<ticketid> +sub comment { + my ($action) = @_; + my (%data, $id, @files, @bcc, @cc, $msg, $wtime, $edit); + my $bad = 0; -Comments and replies + while (@ARGV) { + $_ = shift @ARGV; - --comment - --reply|respond - --source <path> - Specify the path to the source file for this ticket update + if (/^-e$/) { + $edit = 1; + } + elsif (/^-[abcmw]$/) { + unless (@ARGV) { + whine "No argument specified with $_."; + $bad = 1; last; + } + + if (/-a/) { + unless (-f $ARGV[0] && -r $ARGV[0]) { + whine "Cannot read attachment: '$ARGV[0]'."; + exit -1; + } + push @files, shift @ARGV; + } + elsif (/-([bc])/) { + my $a = $_ eq "-b" ? \@bcc : \@cc; + @$a = split /\s*,\s*/, shift @ARGV; + } + elsif (/-m/) { $msg = shift @ARGV } + elsif (/-w/) { $wtime = shift @ARGV } + } + elsif (!$id && m|^(?:ticket/)?($idlist)$|) { + $id = $1; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } - --noedit - Don't invoke \$EDITOR to edit the content of this update + unless ($id) { + whine "No object specified."; + $bad = 1; + } + return help($action, "ticket") if $bad; + + my $form = [ + "", + [ "Ticket", "Action", "Cc", "Bcc", "Attachment", "TimeWorked", "Text" ], + { + Ticket => $id, + Action => $action, + Cc => [ @cc ], + Bcc => [ @bcc ], + Attachment => [ @files ], + TimeWorked => $wtime || '', + Text => $msg || '', + } + ]; + + my $text = Form::compose([ $form ]); + + if ($edit || !$msg) { + my $error = 0; + my ($c, $o, $k, $e); + + do { + my $ntext = vi($text); + exit if ($error && $ntext eq $text); + $text = $ntext; + $form = Form::parse($text); + $error = 0; + + ($c, $o, $k, $e) = @{ $form->[0] }; + if ($e) { + $error = 1; + $c = "# Syntax error."; + goto NEXT; + } + elsif (!@$o) { + exit; + } + @files = @{ vsplit($k->{Attachment}) }; + + NEXT: + $text = Form::compose([[$c, $o, $k, $e]]); + } while ($error); + } + my $i = 1; + foreach my $file (@files) { + $data{"attachment_$i"} = bless([ $file ], "Attachment"); + $i++; + } + $data{content} = $text; + my $r = submit("$REST/ticket/comment/$id", \%data); + print $r->content; +} +# Merge one ticket into another. - Condiments +sub merge { + my @id; + my $bad = 0; - --verbose - --debug - --version - --help|h|usage - You're reading it. + while (@ARGV) { + $_ = shift @ARGV; -EOUSAGE + if (/^\d+$/) { + push @id, $_; + } + else { + whine "Unrecognised argument: '$_'."; + $bad = 1; last; + } + } - exit(0); -} + unless (@id == 2) { + my $evil = @id > 2 ? "many" : "few"; + whine "Too $evil arguments specified."; + $bad = 1; + } + return help("merge", "ticket") if $bad; -# Print version, and leave -if ($version) { - print "RT $RT::VERSION for $RT::rtname. Copyright 1996-2001 Jesse Vincent <jesse\@fsck.com>\n"; - exit(0); + my $r = submit("$REST/ticket/merge/$id[0]", {into => $id[1]}); + print $r->content; } -# }}} - -# {{{ Validate any options that were passed in. normalize them. +# Link one ticket to another. -#if a queue was specified -if ($queue) { - # make sure that $queue is a valid queue and load it into $queue_obj -} +sub link { + my ($bad, $del, %data) = (0, 0, ()); + my %ltypes = map { lc $_ => $_ } qw(DependsOn DependedOnBy RefersTo + ReferredToBy HasMember MemberOf); -#For each date in: $due, $starts, $started + while (@ARGV && $ARGV[0] =~ /^-/) { + $_ = shift @ARGV; -# load up an RT::Date object and parse it into a normalized form -# if it can't parse it, log an error and null out the variable + if (/^-d$/) { + $del = 1; + } + else { + whine "Unrecognised option: '$_'."; + $bad = 1; last; + } + } -# }}} + if (@ARGV == 3) { + my ($from, $rel, $to) = @ARGV; + if ($from !~ /^\d+$/ || $to !~ /^\d+$/) { + my $bad = $from =~ /^\d+$/ ? $to : $from; + whine "Invalid ticket ID '$bad' specified."; + $bad = 1; + } + unless (exists $ltypes{lc $rel}) { + whine "Invalid relationship '$rel' specified."; + $bad = 1; + } + %data = (id => $from, rel => $rel, to => $to, del => $del); + } + else { + my $bad = @ARGV < 3 ? "few" : "many"; + whine "Too $bad arguments specified."; + $bad = 1; + } + return help("link", "ticket") if $bad; -# {{{ Check if we're creating, if so, create the ticket and be done + my $r = submit("$REST/ticket/link", \%data); + print $r->content; +} -if ($create) { - $RT::Logger->debug("Creating a new ticket"); +# Grant/revoke a user's rights. - #Make sure the current user can create tickets in this queue - - #Make sure that the owner specified can own tickets in this queue +sub grant { + my ($cmd) = @_; + my $revoke = 0; + while (@ARGV) { + } - - my $linesref = GetMessageContent( Edit => $edit, Source => $source, - CurrentUser => $CurrentUser - ); - - require MIME::Entity; - my $MIMEObj; - - if ($linesref) { - $MIMEObj = MIME::Entity->build(Data => $linesref); - } - - use RT::Ticket; - my $Ticket=new RT::Ticket($CurrentUser); - my ($ticket, $trans, $msg) = - $Ticket->Create(Queue => $queue, - Owner => $owner, - Status => $status || 'new' , - Subject => $subject, - Requestor => \@requestors, - Cc => \@cc, - AdminCc => \@admincc, - Due => $due, - Starts => $starts, - Started => $started, - TimeLeft => $time_left, - InitialPriority => $priority, - FinalPriority => $final_priority, - MIMEObj => $MIMEObj - ); - print $msg . "\n"; + $revoke = 1 if $cmd->{action} eq 'revoke'; } -# }}} - -else { - #Apply restrictions - use RT::Tickets; - my $Tickets = new RT::Tickets($CurrentUser); - - # {{{ Limit our search - my $value; #to use when iterating through restrictions - my $queue_id; #to use when limiting by keyword - - # {{{ limit on id - - foreach $value (@id) { - if ($value =~ /^(\d+)$/) { - $Tickets->LimitId ( VALUE => $1, - OPERATOR => '='); - } - elsif ($value =~ /^(\d*)\D?(\d*)$/) { - my $start = $1; - my $end = $2; - $Tickets->LimitId( - VALUE => "$start", - OPERATOR => '>=') if ($start); - $Tickets->LimitId( - VALUE => "$end", - OPERATOR => '<=') if ($end); - } +# Client <-> Server communication. +# -------------------------------- +# +# This function composes and sends an HTTP request to the RT server, and +# interprets the response. It takes a request URI, and optional request +# data (a string, or a reference to a set of key-value pairs). + +sub submit { + my ($uri, $content) = @_; + my ($req, $data); + my $ua = new LWP::UserAgent(agent => "RT/3.0b", env_proxy => 1); + + # Did the caller specify any data to send with the request? + $data = []; + if (defined $content) { + unless (ref $content) { + # If it's just a string, make sure LWP handles it properly. + # (By pretending that it's a file!) + $content = [ content => [undef, "", Content => $content] ]; + } + elsif (ref $content eq 'HASH') { + my @data; + foreach my $k (keys %$content) { + if (ref $content->{$k} eq 'ARRAY') { + foreach my $v (@{ $content->{$k} }) { + push @data, $k, $v; + } + } + else { push @data, $k, $content->{$k} } + } + $content = \@data; + } + $data = $content; } + # Should we send authentication information to start a new session? + if (!defined $session->cookie) { + push @$data, ( user => $config{user} ); + push @$data, ( pass => $config{passwd} || read_passwd() ); + } - # }}} - - # {{{ limit on status - - foreach $value (@limit_status) { - if ($value =~ /^(=|!=|!|)(.*)$/) { - my $op = $1; - my $val = $2; - - - $op = ParseBooleanOp($op); - $Tickets->LimitStatus(VALUE => "$val", - OPERATOR => "$op"); - } + # Now, we construct the request. + if (@$data) { + $req = POST($uri, $data, Content_Type => 'form-data'); } + else { + $req = GET($uri); + } + $session->add_cookie_header($req); + + # Then we send the request and parse the response. + DEBUG(3, $req->as_string); + my $res = $ua->request($req); + DEBUG(3, $res->as_string); + + if ($res->is_success) { + # The content of the response we get from the RT server consists + # of an HTTP-like status line followed by optional header lines, + # a blank line, and arbitrary text. + + my ($head, $text) = split /\n\n/, $res->content, 2; + my ($status, @headers) = split /\n/, $head; + $text =~ s/\n*$/\n/; + + # "RT/3.0.1 401 Credentials required" + if ($status !~ m#^RT/\d+(?:\.\d+)+(?:-?\w+)? (\d+) ([\w\s]+)$#) { + warn "rt: Malformed RT response from $config{server}.\n"; + warn "(Rerun with RTDEBUG=3 for details.)\n" if $config{debug} < 3; + exit -1; + } - # }}} - - - - # {{{ limit on queue - foreach $value (@limit_queue) { - if ($value =~ /^(\W?)(.*?)$/i) { - my $op = $1; - my $val = $2; - - $op = ParseBooleanOp($op); - - my $queue_obj = new RT::Queue($RT::SystemUser); - - unless ($queue_obj->Load($val)) { - $RT::Logger->debug("Queue '$val' not found"); - print STDERR "Queue '$val' not found\n"; - exit(-1); - } - $RT::Logger->debug ("Limiting queue to $op ".$queue_obj->Name); - $Tickets->LimitQueue(VALUE => $queue_obj->Name, - OPERATOR => $op); - $queue_id=$queue_obj->id; - } - } - - # {{{ limit on keyword - foreach $value (@limit_keyword) { - if ($value =~ /^(\W?)(.*?)\/(.*)$/i) { - my $op = $1; - my $select = $2; - my $keyword = $3; - - $op = ParseBooleanOp($op); - - # load the keyword select - my $keyselect = RT::KeywordSelect->new($RT::SystemUser); - unless ($keyselect->LoadByName(Name=>$select, Queue=>$queue_id)) { - $RT::Logger->debug("KeywordSelect '$select' not found"); - print STDERR "KeywordSelect '$select' not fount\n"; - exit(-1); - } - - # load the keyword - my $k = RT::Keyword->new($RT::SystemUser); - unless ($k->LoadByNameAndParentId($keyword, $keyselect->Keyword)) { - $RT::Logger->debug("Keyword '$keyword' not found"); - print STDERR "Keyword '$keyword' not found\n"; - exit(-1); - } - $Tickets->LimitKeyword(OPERATOR => $op, - KEYWORDSELECT => $keyselect->id, - KEYWORD => $k->id); - $RT::Logger->debug ("Limiting keyword to $op ".$k->Path); - } + # Our caller can pretend that the server returned a custom HTTP + # response code and message. (Doing that directly is apparently + # not sufficiently portable and uncomplicated.) + $res->code($1); + $res->message($2); + $res->content($text); + $session->update($res) if ($res->is_success || $res->code != 401); + + if (!$res->is_success) { + # We can deal with authentication failures ourselves. Either + # we sent invalid credentials, or our session has expired. + if ($res->code == 401) { + my %d = @$data; + if (exists $d{user}) { + warn "rt: Incorrect username or password.\n"; + exit -1; + } + elsif ($req->header("Cookie")) { + # We'll retry the request with credentials, unless + # we only wanted to logout in the first place. + $session->delete; + return submit(@_) unless $uri eq "$REST/logout"; + } + } + # Conflicts should be dealt with by the handler and user. + # For anything else, we just die. + elsif ($res->code != 409) { + warn "rt: ", $res->content; + exit; + } + } } - # }}} - # {{{ limit on owner - foreach $value (@limit_owner) { - if ($value =~ /^(\W?)(.*?)$/i) { - my $op = $1; - my $val = $2; - - $op = ParseBooleanOp($op); - - my $user_obj = new RT::User($RT::SystemUser); - - unless ($user_obj->Load($val)) { - $RT::Logger->debug("User '$val' not found"); - print STDERR "User '$val' not found\n"; - exit(-1); - } - $val = $user_obj->id(); - - $RT::Logger->debug ("Limiting owner to $op $val"); - $Tickets->LimitOwner(VALUE => "$val", - OPERATOR => "$op"); - } - } - # }}} - # {{{ limt on priority - - foreach $value (@limit_priority) { - my ($start, $end) = ParseRange($value); - if ($start == $end) { - $Tickets->LimitPriority( VALUE => $start, - OPERATOR => '='); - } elsif ($start) { - $Tickets->LimitPriority( VALUE => $start, - OPERATOR => '>='); - } elsif ($end) { - $Tickets->LimitPriority( VALUE => $end, - OPERATOR => '<='); - } - + else { + warn "rt: Server error: ", $res->message, " (", $res->code, ")\n"; + exit -1; } - foreach $value (@limit_final_priority) { - my ($start, $end) = ParseRange($value); - if ($start == $end) { - $Tickets->LimitFinalPriority( VALUE => $start, - OPERATOR => '='); - } elsif ($start) { - $Tickets->LimitFinalPriority( VALUE => $start, - OPERATOR => '>='); - } elsif ($end) { - $Tickets->LimitFinalPriority( VALUE => $end, - OPERATOR => '<='); - } + + return $res; +} + +# Session management. +# ------------------- +# +# Maintains a list of active sessions in the ~/.rt_sessions file. +{ + package Session; + my ($s, $u); + + # Initialises the session cache. + sub new { + my ($class, $file) = @_; + my $self = { + file => $file || "$HOME/.rt_sessions", + sids => { } + }; + + # The current session is identified by the currently configured + # server and user. + ($s, $u) = @config{"server", "user"}; + + bless $self, $class; + $self->load(); + + return $self; } - # }}} - - foreach $value (@limit_requestor) { - if ($value =~ /^(\W?)(.*?)$/i) { - my $op = $1; - my $val = $2; - - $op = ParseBooleanOp($op); - $Tickets->LimitRequestor(VALUE => $val, - OPERATOR => $op ); - } - + + # Returns the current session cookie. + sub cookie { + my ($self) = @_; + my $cookie = $self->{sids}{$s}{$u}; + return defined $cookie ? "RT_SID=$cookie" : undef; } - foreach $value (@limit_subject) { - - if ($value =~ /^(\W?)(.*?)$/i) { - my $op = $1; - my $val = $2; - - $op = ParseLikeOp($op); - - $Tickets->LimitSubject(VALUE => $val, - OPERATOR => $op ); - } + + # Deletes the current session cookie. + sub delete { + my ($self) = @_; + delete $self->{sids}{$s}{$u}; } - - foreach $value (@limit_body) { - if ($value =~ /^(\W?)(.*?)$/i) { - my $op = $1; - my $val = $2; - - $op = ParseLikeOp($op); - - $Tickets->LimitBody(VALUE => $val, - OPERATOR => $op ); - } - + + # Adds a Cookie header to an outgoing HTTP request. + sub add_cookie_header { + my ($self, $request) = @_; + my $cookie = $self->cookie(); + + $request->header(Cookie => $cookie) if defined $cookie; } - - - - # Dates - foreach my $date (@limit_created) { - my ($start, $end) = ParseDateRange($date); - $Tickets->LimitCreated ( VALUE => $start, - OPERATOR => '>=' ) if ($start); - $Tickets->LimitCreated ( VALUE => $end, - OPERATOR => '<=' ) if ($end); + + # Extracts the Set-Cookie header from an HTTP response, and updates + # session information accordingly. + sub update { + my ($self, $response) = @_; + my $cookie = $response->header("Set-Cookie"); + + if (defined $cookie && $cookie =~ /^RT_SID=([0-9A-Fa-f]+);/) { + $self->{sids}{$s}{$u} = $1; + } } - foreach my $date (@limit_due) { - my ($start, $end) = ParseDateRange($date); - $Tickets->LimitDue ( VALUE => $start, - OPERATOR => '>=' ) if ($start); - $Tickets->LimitDue ( VALUE => $end, - OPERATOR => '<=' ) if ($end); + # Loads the session cache from the specified file. + sub load { + my ($self, $file) = @_; + $file ||= $self->{file}; + local *F; + + open(F, $file) && do { + $self->{file} = $file; + my $sids = $self->{sids} = {}; + while (<F>) { + chomp; + next if /^$/ || /^#/; + next unless m#^https?://[^ ]+ \w+ [0-9A-Fa-f]+$#; + my ($server, $user, $cookie) = split / /, $_; + $sids->{$server}{$user} = $cookie; + } + return 1; + }; + return 0; } - foreach my $date (@limit_starts) { - my ($start, $end) = ParseDateRange($date); - $Tickets->LimitStarts ( VALUE => $start, - OPERATOR => '>=' ) if ($start); - $Tickets->LimitStarts ( VALUE => $end, - OPERATOR => '<=' ) if ($end); + # Writes the current session cache to the specified file. + sub save { + my ($self, $file) = shift; + $file ||= $self->{file}; + local *F; + + open(F, ">$file") && do { + my $sids = $self->{sids}; + foreach my $server (keys %$sids) { + foreach my $user (keys %{ $sids->{$server} }) { + my $sid = $sids->{$server}{$user}; + if (defined $sid) { + print F "$server $user $sid\n"; + } + } + } + close(F); + chmod 0600, $file; + return 1; + }; + return 0; } - foreach my $date (@limit_started) { - my ($start, $end) = ParseDateRange($date); - $Tickets->LimitStarted ( VALUE => $start, - OPERATOR => '>=' ) if ($start); - $Tickets->LimitStarted ( VALUE => $end, - OPERATOR => '<=' ) if ($end); + sub DESTROY { + my $self = shift; + $self->save; } +} - foreach my $date (@limit_resolved) { - my ($start, $end) = ParseDateRange($date); - $Tickets->LimitResolved ( VALUE => $start, - OPERATOR => '>=' ) if ($start); - $Tickets->LimitResolved ( VALUE => $end, - OPERATOR => '<=' ) if ($end); +# Form handling. +# -------------- +# +# Forms are RFC822-style sets of (field, value) specifications with some +# initial comments and interspersed blank lines allowed for convenience. +# Sets of forms are separated by --\n (in a cheap parody of MIME). +# +# Each form is parsed into an array with four elements: commented text +# at the start of the form, an array with the order of keys, a hash with +# key/value pairs, and optional error text if the form syntax was wrong. + +# Returns a reference to an array of parsed forms. +sub Form::parse { + my $state = 0; + my @forms = (); + my @lines = split /\n/, $_[0]; + my ($c, $o, $k, $e) = ("", [], {}, ""); + + LINE: + while (@lines) { + my $line = shift @lines; + + next LINE if $line eq ''; + + if ($line eq '--') { + # We reached the end of one form. We'll ignore it if it was + # empty, and store it otherwise, errors and all. + if ($e || $c || @$o) { + push @forms, [ $c, $o, $k, $e ]; + $c = ""; $o = []; $k = {}; $e = ""; + } + $state = 0; + } + elsif ($state != -1) { + if ($state == 0 && $line =~ /^#/) { + # Read an optional block of comments (only) at the start + # of the form. + $state = 1; + $c = $line; + while (@lines && $lines[0] =~ /^#/) { + $c .= "\n".shift @lines; + } + $c .= "\n"; + } + elsif ($state <= 1 && $line =~ /^($field):(?:\s+(.*))?$/) { + # Read a field: value specification. + my $f = $1; + my @v = ($2 || ()); + + # Read continuation lines, if any. + while (@lines && ($lines[0] eq '' || $lines[0] =~ /^\s+/)) { + push @v, shift @lines; + } + pop @v while (@v && $v[-1] eq ''); + + # Strip longest common leading indent from text. + my $ws = ""; + foreach my $ls (map {/^(\s+)/} @v[1..$#v]) { + $ws = $ls if (!$ws || length($ls) < length($ws)); + } + s/^$ws// foreach @v; + + push(@$o, $f) unless exists $k->{$f}; + vpush($k, $f, join("\n", @v)); + + $state = 1; + } + elsif ($line !~ /^#/) { + # We've found a syntax error, so we'll reconstruct the + # form parsed thus far, and add an error marker. (>>) + $state = -1; + $e = Form::compose([[ "", $o, $k, "" ]]); + $e.= $line =~ /^>>/ ? "$line\n" : ">> $line\n"; + } + } + else { + # We saw a syntax error earlier, so we'll accumulate the + # contents of this form until the end. + $e .= "$line\n"; + } } + push(@forms, [ $c, $o, $k, $e ]) if ($e || $c || @$o); - foreach my $date (@limit_lastupdated) { - my ($start, $end) = ParseDateRange($date); - $Tickets->LimitLastUpdated( VALUE => $start, - OPERATOR => '>=' ) if ($start); - $Tickets->LimitLastUpdated ( VALUE => $end, - OPERATOR => '<=' ) if ($end); + foreach my $l (keys %$k) { + $k->{$l} = vsplit($k->{$l}) if (ref $k->{$l} eq 'ARRAY'); } - foreach my $link (@limit_memberof) { - $Tickets->LimitMemberOf($link); - } + return \@forms; +} - foreach my $link (@limit_hasmember) { - $Tickets->LimitHasMember($link); - } +# Returns text representing a set of forms. +sub Form::compose { + my ($forms) = @_; + my @text; - foreach my $link (@limit_dependson) { - $Tickets->LimitDependsOn($link); - } + foreach my $form (@$forms) { + my ($c, $o, $k, $e) = @$form; + my $text = ""; - foreach my $link (@limit_dependedonby) { - $Tickets->LimitDependedOnBy($link); + if ($c) { + $c =~ s/\n*$/\n/; + $text = "$c\n"; + } + if ($e) { + $text .= $e; + } + elsif ($o) { + my @lines; + + foreach my $key (@$o) { + my ($line, $sp); + my $v = $k->{$key}; + my @values = ref $v eq 'ARRAY' ? @$v : $v; + + $sp = " "x(length("$key: ")); + $sp = " "x4 if length($sp) > 16; + + foreach $v (@values) { + if ($v =~ /\n/) { + $v =~ s/^/$sp/gm; + $v =~ s/^$sp//; + + if ($line) { + push @lines, "$line\n\n"; + $line = ""; + } + elsif (@lines && $lines[-1] !~ /\n\n$/) { + $lines[-1] .= "\n"; + } + push @lines, "$key: $v\n\n"; + } + elsif ($line && + length($line)+length($v)-rindex($line, "\n") >= 70) + { + $line .= ",\n$sp$v"; + } + else { + $line = $line ? "$line, $v" : "$key: $v"; + } + } + + $line = "$key:" unless @values; + if ($line) { + if ($line =~ /\n/) { + if (@lines && $lines[-1] !~ /\n\n$/) { + $lines[-1] .= "\n"; + } + $line .= "\n"; + } + push @lines, "$line\n"; + } + } + + $text .= join "", @lines; + } + else { + chomp $text; + } + push @text, $text; } - foreach my $link (@limit_refersto) { - $Tickets->LimitRefersTo($link); - } - - foreach my $link (@limit_referredtoby) { - $Tickets->LimitReferredToBy($link); - } - - if ($limit_first){ - } - if ($limit_rows){ - } + return join "\n--\n\n", @text; +} -# }}} - - # {{{ Iterate through all tickets we found +# Configuration. +# -------------- +# Returns configuration information from the environment. +sub config_from_env { + my %env; - my ($format, $titles, $code); - - #Set up the summary format if we need to - if (defined $summary) { - my $format_string = $summary || $ENV{'RT_SUMMARY_FORMAT'} || "%id4%status4%queue7%subject40%requestor16"; + foreach my $k ("DEBUG", "USER", "PASSWD", "SERVER") { + if (exists $ENV{"RT$k"}) { + $env{lc $k} = $ENV{"RT$k"}; + } + } - ($format, $titles, $code) = BuildListingFormat($format_string); - printf "$format\n", eval "$titles"; - } + return %env; +} - +# Finds a suitable configuration file and returns information from it. +sub config_from_file { + my ($rc) = @_; - while (my $Ticket = $Tickets->Next()) { - $RT::Logger->debug ("Now working on ticket ". $Ticket->id); - - #Run through all the ticket modifications we might want to do - #TODO: these are all insufficiently lazy and should be replaced with some - # nice foreaches. - - - # {{{ deal with watchers - - # add / delete requestors - foreach $value (@requestors) { - if ($value =~ /^(\W?)(.*)$/) { - my $op = $1; - my $addr = $2; - - $Ticket->AddRequestor(Email => $addr) if ($op eq '+'); - $Ticket->DeleteRequestor( $addr) if ($op eq '-'); - } - } - - # add / delete ccs - foreach $value (@cc) { - if ($value =~ /^(\W?)(.*)$/) { - my $op = $1; - my $addr = $2; - $Ticket->AddCc(Email => $addr) if ($op eq '+'); - $Ticket->DeleteCc($addr) if ($op eq '-'); - } - } - - # add / delete adminccs - $RT::Logger->debug("Looking at admin ccs"); - foreach $value (@admincc) { - if ($value =~ /^(\W?)(.*)$/) { - my $op = $1; - my $addr = $2; - $Ticket->AddAdminCc(Email => $addr) if ($op eq '+'); - $Ticket->DeleteAdminCc($addr) if ($op eq '-'); - } - } - - # }}} - - # {{{ Deal with ticket keywords - - my $KeywordSelects = $Ticket->QueueObj->KeywordSelects(); - $RT::Logger->debug ("Looking at keywords"); - foreach $value (@keywords) { - $RT::Logger->debug("Looking at --keyword=$value"); - if ($value =~ /^(\W?)(.*?)\/(.*)$/) { - my $op = $1; - my $select = $2; - my $keyword = $3; - - $RT::Logger->debug("Going to $op Keyword $select / $keyword"); - while (my $ks = $KeywordSelects->Next) { - $RT::Logger->debug("$select is select ".$ks->Name." is found"); - next unless ($ks->Name =~ /$select/i); - $RT::Logger->debug ("Found a match for $select\n"); - my $kids = $ks->KeywordObj->Descendents; - - my ($kid); - foreach $kid (keys %{$kids}) { - $RT::Logger->debug("Now comparing $keyword with ".$kids->{$kid}. "\n"); - next unless ($kids->{$kid} =~ /^$keyword$/i); - $RT::Logger->debug("Going to $op $select / $keyword (".$kids->{$kid} .")"); - $Ticket->DeleteKeyword(KeywordSelect => $ks->id, - Keyword => $kid) if ($op eq '-'); - - $Ticket->AddKeyword(KeywordSelect => $ks->id, - Keyword => $kid) if ($op eq '+'); - } - - } - } - } - # }}} - - # {{{ deal with links - - # Deal with merging { - if ($mergeinto) { - my ($trans, $msg) =$Ticket->MergeInto($mergeinto); - print $msg."\n"; - } - # add /delete depends-ons - - foreach my $value (@dependson) { - if ($value =~ /^(\W?)(.*)$/) { - my $op = $1; - my $ticket = $2; - if (!$op or ($op eq '+')) { - my ($trans, $msg) = - $Ticket->AddLink(Type => 'DependsOn', Target => $ticket); - print $msg."\n"; - } - elsif ($op eq '-') { - my ($trans, $msg) = - $Ticket->DeleteLink(Type => 'DependsOn', Target => $ticket); - print $msg."\n"; - } - - } - } - # add /delete member-of - foreach my $value (@memberof) { - if ($value =~ /^(\W?)(.*)$/) { - my $op = $1; - my $ticket = $2; - if ($op eq '+') { - my ($trans, $msg) = - $Ticket->AddLink(Type => 'MemberOf', Target => $ticket); - print $msg; - } - elsif ($op eq '-') { - my ($trans, $msg) = - $Ticket->DeleteLink(Type => 'MemberOf', Target => $ticket); - print $msg; - } - - } - } - # add / delete refers-to - foreach my $value (@refersto) { - if ($value =~ /^(\W?)(.*)$/) { - my $op = $1; - my $ticket = $2; - if ($op eq '+') { - my ($trans, $msg) = - $Ticket->AddLink(Type => 'RefersTo', Target => $ticket); - print $msg; - } - elsif ($op eq '-') { - my ($trans, $msg) = - $Ticket->DeleteLink(Type => 'RefersTo', Target => $ticket); - print $msg; - } - - } - } - - # }}} - - # {{{ deal with dates - - #set due - if ($due) { - my $iso = ParseDateToISO($due); - if ($iso) { - $RT::Logger->debug("Setting due date to $iso ($due)"); - my ($trans, $msg) = - $Ticket->SetDue($iso); - print $msg; - } - else { - print "Due date '$due' could not be parsed"; - } - } - - #set starts - if ($starts) { - my $iso = ParseDateToISO($due); - if ($iso) { - my ($trans, $msg) = - $Ticket->SetStarts($iso); - print $msg."\n"; - } - else { - print "Starts date '$starts' could not be parsed"; - } - } - #set started - if ($started) { - my $iso = ParseDateToISO($started); - if ($iso) { - my ($trans, $msg) = - $Ticket->SetStarted($iso); - print $msg."\n"; - } - else { - print "Started date '$started' could not be parsed"; - } - } - #set contacted - if ($contacted) { - my $iso = ParseDateToISO($contacted); - if ($iso) { - my ($trans, $msg) = - $Ticket->SetContacted($iso); - print $msg."\n"; - } - else { - print "Contacted date '$contacted' could not be parsed"; - } - } - - # }}} - - # {{{ set other attributes - - #Set subject - if ($subject) { - my ($trans, $msg) = $Ticket->SetSubject($subject); - print $msg."\n"; - } - - #Set priority - if ($priority) { - my ($trans, $msg) = - $Ticket->SetPriority($priority); - print $msg."\n"; - } - - #Set final priority - if ($final_priority) { - my ($trans, $msg) = - $Ticket->SetFinalPriority($final_priority); - print $msg."\n"; - } - - #Set status - if ($status) { - my ($trans, $msg) = - $Ticket->SetStatus($status); - print $msg."\n"; - } - - #Set time left - if ($time_left) { - my ($trans, $msg) = - $Ticket->SetTimeLeft($time_left); - print $msg."\n"; - } - - #Set time_taken - if ($time_taken) { - my ($trans, $msg) = - $Ticket->SetTimeTaken($time_taken); - print $msg."\n"; - } - - #Set owner - if ($owner) { - my ($trans, $msg) = - $Ticket->SetOwner($owner); - print $msg."\n"; - } - - # Steal - if ($steal) { - my ($trans, $msg) = - $Ticket->Steal(); - print $msg . "\n"; + if ($rc =~ m#^/#) { + # We'll use an absolute path if we were given one. + return parse_config_file($rc); + } + else { + # Otherwise we'll use the first file we can find in the current + # directory, or in one of its (increasingly distant) ancestors. + + my @dirs = split /\//, cwd; + while (@dirs) { + my $file = join('/', @dirs, $rc); + if (-r $file) { + return parse_config_file($file); + } + + # Remove the last directory component each time. + pop @dirs; + } + + # Still nothing? We'll fall back to some likely defaults. + for ("$HOME/$rc", "/etc/rt.conf") { + return parse_config_file($_) if (-r $_); } - #Set queue - if ($queue) { - my ($trans, $msg) = - $Ticket->SetQueue($queue); - print $msg."\n"; - } - - # }}} - - - - # {{{ Perform ticket comments/replies - if ($reply) { - $RT::Logger->debug("Replying to ticket ".$Ticket->Id); - - my $linesref = GetMessageContent( Edit => $edit, Source => $source, - CurrentUser => $CurrentUser - ); - - #TODO build this entity - require MIME::Entity; - my $MIMEObj = MIME::Entity->build(Data => $linesref); - - $Ticket->Correspond( MIMEObj => $MIMEObj , - TimeTaken => $time_taken); - } - - elsif ($comment) { - $RT::Logger->debug("Commenting on ticket ".$Ticket->Id); - - my $linesref =GetMessageContent(Edit => $edit, Source => $source, - CurrentUser => $CurrentUser); - #TODO build this entity - require MIME::Entity; - my $MIMEObj = MIME::Entity->build(Data => $linesref); - - $Ticket->Comment( MIMEObj => $MIMEObj, - TimeTaken => $time_taken); - } - - # }}} - - # {{{ Display whatever we need to display - - # {{{ Display a full ticket listing and history - if ($history) { - #Display the history - $RT::Logger->debug("Show history for ".$Ticket->id); - - if ($Ticket->CurrentUserHasRight("ShowTicket")) { - &ShowSummary($Ticket); - print "\n"; - &ShowHistory($Ticket); - } - else { - print "You don't have permission to view that ticket.\n"; - } - } - - # }}} - - # {{{ Display a summary if we need to - if (defined $summary) { - $RT::Logger->debug ("Show ticket summary with format $format"); - - printf $format."\n", eval $code; - - } - # }}} - - # }}} - } - # }}} - + return (); } +# Makes a hash of the specified configuration file. +sub parse_config_file { + my %cfg; + my ($file) = @_; + + open(CFG, $file) && do { + while (<CFG>) { + chomp; + next if (/^#/ || /^\s*$/); + + if (/^(user|passwd|server)\s+([^ ]+)$/) { + $cfg{$1} = $2; + } + else { + die "rt: $file:$.: unknown configuration directive.\n"; + } + } + }; -$RT::Handle->Disconnect(); + return %cfg; +} +# Helper functions. +# ----------------- +sub whine { + my $sub = (caller(1))[3]; + $sub =~ s/^main:://; + warn "rt: $sub: @_\n"; + return; +} +sub read_passwd { + eval 'require Term::ReadKey'; + if ($@) { + die "No password specified (and Term::ReadKey not installed).\n"; + } + print "Password: "; + Term::ReadKey::ReadMode('noecho'); + chomp(my $passwd = Term::ReadKey::ReadLine(0)); + Term::ReadKey::ReadMode('restore'); + print "\n"; + return $passwd; +} +sub vi { + my ($text) = @_; + my $file = "/tmp/rt.form.$$"; + my $editor = $ENV{EDITOR} || $ENV{VISUAL} || "vi"; -# {{{ sub ParseBooleanOp + local *F; + local $/ = undef; -=head2 ParseBooleanOp + open(F, ">$file") || die "$file: $!\n"; print F $text; close(F); + system($editor, $file) && die "Couldn't run $editor.\n"; + open(F, $file) || die "$file: $!\n"; $text = <F>; close(F); + unlink($file); - Takes an option modifier. returns the apropriate SQL operator. - If it's handed ! or -, returns !=. Otherwise returns =. + return $text; +} -=cut +# Add a value to a (possibly multi-valued) hash key. +sub vpush { + my ($hash, $key, $val) = @_; + my @val = ref $val eq 'ARRAY' ? @$val : $val; -sub ParseBooleanOp { - - my $op = shift; - - #so that !new limits to not new, etc - if ($op =~ /^(\!|-)/) { - $op = "!="; + if (exists $hash->{$key}) { + unless (ref $hash->{$key} eq 'ARRAY') { + my @v = $hash->{$key} ne '' ? $hash->{$key} : (); + $hash->{$key} = \@v; + } + push @{ $hash->{$key} }, @val; } else { - $op = "="; + $hash->{$key} = $val; } - - return($op); } -# }}} +# "Normalise" a hash key that's known to be multi-valued. +sub vsplit { + my ($val) = @_; + my ($word, @words); + my @values = ref $val eq 'ARRAY' ? @$val : $val; + + foreach my $line (map {split /\n/} @values) { + # XXX: This should become a real parser, à la Text::ParseWords. + $line =~ s/^\s+//; + $line =~ s/\s+$//; + push @words, split /\s*,\s*/, $line; + } + + return \@words; +} + +sub expand_list { + my ($list) = @_; + my ($elt, @elts, %elts); -# {{{ sub ParseLikeOp -=head2 ParseLikeOp + foreach $elt (split /,/, $list) { + if ($elt =~ /^(\d+)-(\d+)$/) { push @elts, ($1..$2) } + else { push @elts, $elt } + } - Takes an option modifier. returns the apropriate SQL operator. - If it's handed ! or -, returns NOT LIKE. Otherwise returns LIKE + @elts{@elts}=(); + return sort {$a<=>$b} keys %elts; +} -=cut +sub get_type_argument { + my $type; -sub ParseLikeOp { - - my $op = shift; - - #so that !new limits to not new, etc - if ($op =~ /^(\!|-)/) { - $op = "NOT LIKE"; + if (@ARGV) { + $type = shift @ARGV; + unless ($type =~ /^[A-Za-z0-9_.-]+$/) { + # We want whine to mention our caller, not us. + @_ = ("Invalid type '$type' specified."); + goto &whine; + } } else { - $op = "LIKE"; + @_ = ("No type argument specified with -t."); + goto &whine; } - - return($op); + + $type =~ s/s$//; # "Plural". Ugh. + return $type; } -# }}} -# {{{ sub ParseDateToISO +sub get_var_argument { + my ($data) = @_; -=head2 ParseDateToISO + if (@ARGV) { + my $kv = shift @ARGV; + if (my ($k, $v) = $kv =~ /^($field)=(.*)$/) { + push @{ $data->{$k} }, $v; + } + else { + @_ = ("Invalid variable specification: '$kv'."); + goto &whine; + } + } + else { + @_ = ("No variable argument specified with -S."); + goto &whine; + } +} -Takes a date in an arbitrary format. -Returns an ISO date and time in GMT +sub is_object_spec { + my ($spec, $type) = @_; -=cut + $spec =~ s|^(?:$type/)?|$type/| if defined $type; + return $spec if ($spec =~ m{^$name/(?:$idlist|$labels)(?:/.*)?$}o); + return; +} -sub ParseDateToISO { - my $date = shift; +__DATA__ - my $date_obj = new RT::Date($CurrentUser); - $date_obj->Set( Format => 'unknown', - Value => $date - ); - return ($date_obj->ISO); -} +Title: intro +Title: introduction +Text: -# }}} + ** THIS IS AN UNSUPPORTED PREVIEW RELEASE ** + ** PLEASE REPORT BUGS TO rt-bugs@fsck.com ** -# {{{ sub ParseDateRange + This is a command-line interface to RT 3. -=head2 ParseDateRange [RANGE] + It allows you to interact with an RT server over HTTP, and offers an + interface to RT's functionality that is better-suited to automation + and integration with other tools. -Takes a range of dates of the form [<date>][-][<date>] and returns -starting and ending dates (as ISOs) If a date is specified as neither a starting nor ending -date, we parse it it as "midnight tonight to midnight tomorrow" + In general, each invocation of this program should specify an action + to perform on one or more objects, and any other arguments required + to complete the desired action. -=cut + For more information: -sub ParseDateRange { - my $in = shift; - my ($start, $end); - - - use RT::Date; - my $start_obj = new RT::Date($CurrentUser); - my $end_obj = new RT::Date($CurrentUser); - - if ($in =~ /^(.*?)-(.*?)$/) { - $start = $1; - $end = $2; - - if ($start) { - $start_obj->Set(Format => 'unknown', - Value => $start); - } - if ($end) { - $end_obj->Set(Format => 'unknown', - Value => $end); - } - } - else { - $start = $in; - $end = $in; - - $start_obj->Set(Format => 'unknown', - Value => $start); - - $end_obj->Set(Format => 'unknown', - Value => $end); - - $start_obj->SetToMidnight(); - $end_obj->SetToMidnight(); - $end_obj->AddDay(); - } - - if ($start) { - $start = $start_obj->ISO; - } - if ($end) { - $end = $end_obj->ISO; - } + - rt help actions (a list of possible actions) + - rt help objects (how to specify objects) + - rt help usage (syntax information) - return ($start, $end); -} + - rt help config (configuration details) + - rt help examples (a few useful examples) + - rt help topics (a list of help topics) -# }}} +-- -# {{{ ParseRange -=head2 ParseRange [RANGE] +Title: usage +Title: syntax +Text: -Takes a range of the form [<int>][-][<int>] and returns -a first and a last value. If the - is omitted, both $start and $end are the same. -=cut + Syntax: -sub ParseRange { - my $in = shift; - my ($start, $end); - - if ($in =~ /(.*?)-(.*?)/) { - $start = $1; - $end = $2; - } - else { - $start = $in; - $end = $in; - } - - return ($start, $end); - + rt <action> [options] [arguments] - -} + Each invocation of this program must specify an action (e.g. "edit", + "create"), options to modify behaviour, and other arguments required + by the specified action. (For example, most actions expect a list of + numeric object IDs to act upon.) -# }}} - -# {{{ sub ShowSummary - -sub ShowSummary { - my $Ticket = shift; - - - print <<EOFORM; -Serial Number: @{[$Ticket->Id]} Status:@{[$Ticket->Status]} Worked: @{[$Ticket->TimeWorked]} minutes Queue:@{[$Ticket->QueueObj->Name]} - Subject: @{[$Ticket->Subject]} - Requestors: @{[$Ticket->RequestorsAsString]} - Cc: @{[$Ticket->CcAsString]} - Admin Cc: @{[$Ticket->AdminCcAsString]} - Owner: @{[$Ticket->OwnerObj->Name]} - Priority: @{[$Ticket->Priority]} / @{[$Ticket->FinalPriority]} - Due: @{[$Ticket->DueAsString]} - Created: @{[$Ticket->CreatedAsString]} (@{[$Ticket->AgeAsString]}) - Last Contact: @{[$Ticket->ToldAsString]} (@{[$Ticket->LongSinceToldAsString]}) - Last Update: @{[$Ticket->LastUpdatedAsString]} by @{[$Ticket->LastUpdatedByObj->Name]} - -EOFORM - -my $selects = $Ticket->QueueObj->KeywordSelects(); - #get the keyword selects - print "Keywords:\n"; - while (my $select = $selects->Next) { - print "\t" .$select->Name .": "; - my $keys = $Ticket->KeywordsObj($select->id); - while (my $key = $keys->Next) { - print $key->KeywordObj->RelativePath($select->KeywordObj) . " "; - - } - print "\n"; - } + The details of the syntax and arguments for each action are given by + "rt help <action>". Some actions may be referred to by more than one + name ("create" is the same as "new", for example). + + Objects are identified by a type and an ID (which can be a name or a + number, depending on the type). For some actions, the object type is + implied (you can only comment on tickets); for others, the user must + specify it explicitly. See "rt help objects" for details. + + In syntax descriptions, mandatory arguments that must be replaced by + appropriate value are enclosed in <>, and optional arguments are + indicated by [] (for example, <action> and [options] above). + + For more information: + + - rt help objects (how to specify objects) + - rt help actions (a list of actions) + - rt help types (a list of object types) + +-- + +Title: conf +Title: config +Title: configuration +Text: + + This program has two major sources of configuration information: its + configuration files, and the environment. + + The program looks for configuration directives in a file named .rtrc + (or $RTCONFIG; see below) in the current directory, and then in more + distant ancestors, until it reaches /. If no suitable configuration + files are found, it will also check for ~/.rtrc and /etc/rt.conf. + + Configuration directives: + + The following directives may occur, one per line: + + - server <URL> URL to RT server. + - user <username> RT username. + - passwd <passwd> RT user's password. + + Blank and #-commented lines are ignored. + + Environment variables: + + The following environment variables override any corresponding + values defined in configuration files: + + - RTUSER + - RTPASSWD + - RTSERVER + - RTDEBUG Numeric debug level. (Set to 3 for full logs.) + - RTCONFIG Specifies a name other than ".rtrc" for the + configuration file. + +-- + +Title: objects +Text: + + Syntax: + + <type>/<id>[/<attributes>] + + Every object in RT has a type (e.g. "ticket", "queue") and a numeric + ID. Some types of objects can also be identified by name (like users + and queues). Furthermore, objects may have named attributes (such as + "ticket/1/history"). + + An object specification is like a path in a virtual filesystem, with + object types as top-level directories, object IDs as subdirectories, + and named attributes as further subdirectories. + + A comma-separated list of names, numeric IDs, or numeric ranges can + be used to specify more than one object of the same type. Note that + the list must be a single argument (i.e., no spaces). For example, + "user/root,1-3,5,7-10,ams" is a list of ten users; the same list + can also be written as "user/ams,root,1,2,3,5,7,8-20". -#iterate through the keyword selects. -#print the keyword select and all the related keywords + Examples: + ticket/1 + ticket/1/attachments + ticket/1/attachments/3 + ticket/1/attachments/3/content + ticket/1-3/links + ticket/1-3,5-7/history + user/ams + user/ams/rights + user/ams,rai,1/rights -#TODO: finish link descriptions -print "Dependencies: \n"; - while (my $l=$Ticket->DependedOnBy->Next) { - print $l->BaseObj->id," (",$l->BaseObj->Subject,") ",$l->Type," this ticket\n"; - } - while (my $l=$Ticket->DependsOn->Next) { - print "This ticket ",$l->Type," ",$l->TargetObj->Id," (",$l->TargetObj->Subject,")\n"; - } -} + For more information: -# }}} - -# {{{ sub ShowHistory -sub ShowHistory { - my $Ticket = shift; - my $Transaction; - my $Transactions = $Ticket->Transactions; - - while ($Transaction = $Transactions->Next) { - &ShowTransaction($Transaction); - } - } -# }}} - -# {{{ sub ShowTransaction -sub ShowTransaction { - my $transaction = shift; - -print <<EOFORM; -========================================================================== -Date: @{[$transaction->CreatedAsString]} (@{[$transaction->TimeTaken]} minutes) -@{[$transaction->Description]} -EOFORM - ; - my $attachments=$transaction->Attachments(); - while (my $message=$attachments->Next) { - print <<EOFORM; --------------------------------------------------------------------------- -@{[$message->Headers]} -EOFORM - - if ($message->ContentType =~ m{^(text/plain|message|text$)}) { - print $message->Content; - } else { - print $message->ContentType, " not shown"; - } - } - print "\n"; - return(); -} -# }}} - - -# {{{ sub BuildListingFormat - -sub BuildListingFormat { - my $format_string = shift; - - my ($id, @format, @code, @titles); - my ($field,$titles,$length, $format); - - my $code = ""; - - # {{{ attribs - my $attribs = { id => { chars => '4', - justify => 'r', - title => 'id', - value => '$Ticket->id', - }, - - queue => { chars => '8', - justify => 'l', - title => 'Queue', - value => '$Ticket->QueueObj->Name' - }, - subject => { chars => '30', - justify => 'l', - title => 'Subject', - value => '$Ticket->Subject', - }, - priority => { chars => '2', - justify => 'r', - title => 'Pri', - value => '$Ticket->Priority', - }, - final_priority => { chars => '2', - justify => 'r', - title => 'Fin', - value => '$Ticket->FinalPriority', - }, - time_worked => { chars => '6', - justify => 'r', - title => 'Worked', - value => '$Ticket->TimeWorked', - }, - time_left => { chars => '5', - justify => 'r', - title => 'Left', - value => '$Ticket->TimeLeft', - - }, - - status => { chars => '6', - justify => 'r', - title => 'Status', - value => '$Ticket->Status', - }, - owner => { chars => '10', - justify => 'r', - title => 'Owner', - value => '$Ticket->OwnerObj->Name' - }, - requestor => { chars => '10', - justify => 'r', - title => 'Requestor', - value => '$Ticket->RequestorsAsString' - }, - created => { chars => '12', - justify => 'r', - title => 'Created', - value => '$Ticket->CreatedAsString' - }, - updated => { chars => '12', - justify => 'r', - title => 'Updated', - value => '$Ticket->LastUpdatedAsString' - }, - due => { chars => '12', - justify => 'r', - title => 'Due', - value => '$Ticket->DueAsString' - }, - told => { chars => '12', - justify => 'r', - title => 'Told', - value => '$Ticket->ToldAsString' - }, - - - - }; - - # }}} + - rt help <action> (action-specific details) + - rt help <type> (type-specific details) + +-- + +Title: actions +Title: commands +Text: + + You can currently perform the following actions on all objects: + + - list (list objects matching some condition) + - show (display object details) + - edit (edit object details) + - create (create a new object) + + Each type may define actions specific to itself; these are listed in + the help item about that type. + + For more information: + + - rt help <action> (action-specific details) + - rt help types (a list of possible types) + +-- + +Title: types +Text: + + You can currently operate on the following types of objects: + + - tickets + - users + - groups + - queues + + For more information: + + - rt help <type> (type-specific details) + - rt help objects (how to specify objects) + - rt help actions (a list of possible actions) + +-- + +Title: ticket +Text: + + Tickets are identified by a numeric ID. + + The following generic operations may be performed upon tickets: + + - list + - show + - edit + - create + + In addition, the following ticket-specific actions exist: + + - link + - merge + - comment + - correspond + + Attributes: + + The following attributes can be used with "rt show" or "rt edit" + to retrieve or edit other information associated with tickets: + + links A ticket's relationships with others. + history All of a ticket's transactions. + history/type/<type> Only a particular type of transaction. + history/id/<id> Only the transaction of the specified id. + attachments A list of attachments. + attachments/<id> The metadata for an individual attachment. + attachments/<id>/content The content of an individual attachment. + +-- + +Title: user +Title: group +Text: + + Users and groups are identified by name or numeric ID. + + The following generic operations may be performed upon them: + + - list + - show + - edit + - create + + In addition, the following type-specific actions exist: + + - grant + - revoke + + Attributes: + + The following attributes can be used with "rt show" or "rt edit" + to retrieve or edit other information associated with users and + groups: + + rights Global rights granted to this user. + rights/<queue> Queue rights for this user. + +-- + +Title: queue +Text: + + Queues are identified by name or numeric ID. + + Currently, they can be subjected to the following actions: + + - show + - edit + - create + +-- + +Title: logout +Text: + + Syntax: + + rt logout + + Terminates the currently established login session. You will need to + provide authentication credentials before you can continue using the + server. (See "rt help config" for details about authentication.) + +-- + +Title: ls +Title: list +Title: search +Text: + + Syntax: + + rt <ls|list|search> [options] "query string" + + Displays a list of objects matching the specified conditions. + ("ls", "list", and "search" are synonyms.) + + Conditions are expressed in the SQL-like syntax used internally by + RT3. (For more information, see "rt help query".) The query string + must be supplied as one argument. + + (Right now, the server doesn't support listing anything but tickets. + Other types will be supported in future; this client will be able to + take advantage of that support without any changes.) + + Options: + + The following options control how much information is displayed + about each matching object: + + -i Numeric IDs only. (Useful for |rt edit -; see examples.) + -s Short description. + -l Longer description. + + In addition, + + -o +/-<field> Orders the returned list by the specified field. + -S var=val Submits the specified variable with the request. + -t type Specifies the type of object to look for. (The + default is "ticket".) + + Examples: + + rt ls "Priority > 5 and Status='new'" + rt ls -o +Subject "Priority > 5 and Status='new'" + rt ls -o -Created "Priority > 5 and Status='new'" + rt ls -i "Priority > 5"|rt edit - set status=resolved + rt ls -t ticket "Subject like '[PATCH]%'" + +-- + +Title: show +Text: + + Syntax: + + rt show [options] <object-ids> + + Displays details of the specified objects. + + For some types, object information is further classified into named + attributes (for example, "1-3/links" is a valid ticket specification + that refers to the links for tickets 1-3). Consult "rt help <type>" + and "rt help objects" for further details. + + This command writes a set of forms representing the requested object + data to STDOUT. + + Options: + + - Read IDs from STDIN instead of the command-line. + -t type Specifies object type. + -f a,b,c Restrict the display to the specified fields. + -S var=val Submits the specified variable with the request. + + Examples: + + rt show -t ticket -f id,subject,status 1-3 + rt show ticket/3/attachments/29 + rt show ticket/3/attachments/29/content + rt show ticket/1-3/links + rt show -t user 2 + +-- + +Title: new +Title: edit +Title: create +Text: + + Syntax: + + rt edit [options] <object-ids> set field=value [field=value] ... + add field=value [field=value] ... + del field=value [field=value] ... + + Edits information corresponding to the specified objects. + + If, instead of "edit", an action of "new" or "create" is specified, + then a new object is created. In this case, no numeric object IDs + may be specified, but the syntax and behaviour remain otherwise + unchanged. + + This command typically starts an editor to allow you to edit object + data in a form for submission. If you specified enough information + on the command-line, however, it will make the submission directly. + + The command line may specify field-values in three different ways. + "set" sets the named field to the given value, "add" adds a value + to a multi-valued field, and "del" deletes the corresponding value. + Each "field=value" specification must be given as a single argument. + + For some types, object information is further classified into named + attributes (for example, "1-3/links" is a valid ticket specification + that refers to the links for tickets 1-3). These attributes may also + be edited. Consult "rt help <type>" and "rt help object" for further + details. + + Options: + + - Read numeric IDs from STDIN instead of the command-line. + (Useful with rt ls ... | rt edit -; see examples below.) + -i Read a completed form from STDIN before submitting. + -o Dump the completed form to STDOUT instead of submitting. + -e Allows you to edit the form even if the command-line has + enough information to make a submission directly. + -S var=val + Submits the specified variable with the request. + -t type Specifies object type. + + Examples: + + # Interactive (starts $EDITOR with a form). + rt edit ticket/3 + rt create -t ticket + + # Non-interactive. + rt edit ticket/1-3 add cc=foo@example.com set priority=3 + rt ls -t tickets -i 'Priority > 5' | rt edit - set status=resolved + rt edit ticket/4 set priority=3 owner=bar@example.com \ + add cc=foo@example.com bcc=quux@example.net + rt create -t ticket subject='new ticket' priority=10 \ + add cc=foo@example.com + +-- + +Title: comment +Title: correspond +Text: + + Syntax: + + rt <comment|correspond> [options] <ticket-id> + + Adds a comment (or correspondence) to the specified ticket (the only + difference being that comments aren't sent to the requestors.) + + This command will typically start an editor and allow you to type a + comment into a form. If, however, you specified all the necessary + information on the command line, it submits the comment directly. + + (See "rt help forms" for more information about forms.) + + Options: + + -m <text> Specify comment text. + -a <file> Attach a file to the comment. (May be used more + than once to attach multiple files.) + -c <addrs> A comma-separated list of Cc addresses. + -b <addrs> A comma-separated list of Bcc addresses. + -w <time> Specify the time spent working on this ticket. + -e Starts an editor before the submission, even if + arguments from the command line were sufficient. + + Examples: + + rt comment -t 'Not worth fixing.' -a stddisclaimer.h 23 + +-- + +Title: merge +Text: + + Syntax: + + rt merge <from-id> <to-id> + + Merges the two specified tickets. + +-- + +Title: link +Text: + + Syntax: + + rt link [-d] <id-A> <relationship> <id-B> + + Creates (or, with -d, deletes) a link between the specified tickets. + The relationship can (irrespective of case) be any of: + + DependsOn/DependedOnBy: A depends upon B (or vice versa). + RefersTo/ReferredToBy: A refers to B (or vice versa). + MemberOf/HasMember: A is a member of B (or vice versa). + + To view a ticket's relationships, use "rt show ticket/3/links". (See + "rt help ticket" and "rt help show".) + + Options: + + -d Deletes the specified link. + + Examples: + + rt link 2 dependson 3 + rt link -d 4 referredtoby 6 # 6 no longer refers to 4 + +-- + +Title: grant +Title: revoke +Text: + +-- + +Title: query +Text: + + RT3 uses an SQL-like syntax to specify object selection constraints. + See the <RT:...> documentation for details. + (XXX: I'm going to have to write it, aren't I?) - foreach $field (split ('%',$format_string)) { - - if ($field =~ /^(\D*?)(\d*?)$/) { - $id = $1; - $length = $2; - } - else { - $RT::Logger->debug ("Error parsing $field\n"); - } - if ($length) { - push (@format, "%".$length.".".$length."s "); - - push (@code, $attribs->{"$id"}->{'value'}); - - push (@titles, "'". $attribs->{"$id"}->{title}. "'"); - } - - - } - $code = join (',', @code); - $format = join (" ", @format); - $titles = join (', ', @titles); +-- + +Title: form +Title: forms +Text: + + This program uses RFC822 header-style forms to represent object data + in a form that's suitable for processing both by humans and scripts. + + A form is a set of (field, value) specifications, with some initial + commented text and interspersed blank lines allowed for convenience. + Field names may appear more than once in a form; a comma-separated + list of multiple field values may also be specified directly. - - return ($format, $titles, $code); -} + Field values can be wrapped as in RFC822, with leading whitespace. + The longest sequence of leading whitespace common to all the lines + is removed (preserving further indentation). There is no limit on + the length of a value. + + Multiple forms are separated by a line containing only "--\n". + + (XXX: A more detailed specification will be provided soon. For now, + the server-side syntax checking will suffice.) + +-- + +Title: topics +Text: + + Use "rt help <topic>" for help on any of the following subjects: + + - tickets, users, groups, queues. + - show, edit, ls/list/search, new/create. + + - query (search query syntax) + - forms (form specification) + + - objects (how to specify objects) + - types (a list of object types) + - actions/commands (a list of actions) + - usage/syntax (syntax details) + - conf/config/configuration (configuration details) + - examples (a few useful examples) + +-- -# }}} +Title: example +Title: examples +Text: + This section will be filled in with useful examples, once it becomes + more clear what examples may be useful. + For the moment, please consult examples provided with each action. -1; +-- diff --git a/rt/bin/rt-crontool b/rt/bin/rt-crontool index ede874a0c..cdbc3cbc9 100644 --- a/rt/bin/rt-crontool +++ b/rt/bin/rt-crontool @@ -197,7 +197,7 @@ sub help { ) . "\n\n"; - print " sbin/cron_shim \\\n"; + print " bin/rt-cron-tool \\\n"; print " --search RT::Search::ActiveTicketsInQueue --search-arg general \\\n"; print @@ -205,6 +205,16 @@ sub help { print " --action RT::Action::SetPriority --action-arg 99 \\\n"; print " --verbose\n"; + print "\n"; + print loc("Escalate tickets"); + print "rt-crontool \\\n"; + print " --search RT::Search::ActiveTicketsInQueue --search-arg thequeuename \\\n"; + print " --action RT::Action::EscalatePriority \\\n"; + + + + + exit(0); } diff --git a/rt/bin/rt-crontool.in b/rt/bin/rt-crontool.in index 73b80aa90..8ecc71826 100644 --- a/rt/bin/rt-crontool.in +++ b/rt/bin/rt-crontool.in @@ -197,7 +197,7 @@ sub help { ) . "\n\n"; - print " sbin/cron_shim \\\n"; + print " bin/rt-cron-tool \\\n"; print " --search RT::Search::ActiveTicketsInQueue --search-arg general \\\n"; print @@ -205,6 +205,16 @@ sub help { print " --action RT::Action::SetPriority --action-arg 99 \\\n"; print " --verbose\n"; + print "\n"; + print loc("Escalate tickets"); + print "rt-crontool \\\n"; + print " --search RT::Search::ActiveTicketsInQueue --search-arg thequeuename \\\n"; + print " --action RT::Action::EscalatePriority \\\n"; + + + + + exit(0); } diff --git a/rt/bin/rt-mailgate b/rt/bin/rt-mailgate index b30443638..8af800227 100755 --- a/rt/bin/rt-mailgate +++ b/rt/bin/rt-mailgate @@ -1,26 +1,26 @@ #!/usr/bin/perl -w # BEGIN LICENSE BLOCK -# +# # Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> -# +# # (Except where explictly superceded by other copyright notices) -# +# # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed # from www.gnu.org. -# +# # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. -# +# # Unless otherwise specified, all modifications, corrections or # extensions to this work which alter its source code become the # property of Best Practical Solutions, LLC when submitted for # inclusion in the work. -# -# +# +# # END LICENSE BLOCK =head1 NAME @@ -31,10 +31,25 @@ rt-mailgate - Mail interface to RT3. use RT::I18N; +# Make sure that when we call the mailgate wrong, it tempfails + +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://bad.address"), "Opened the mailgate - The error below is expected - $@"); +print MAIL <<EOF; +From: root\@localhost +To: rt\@example.com +Subject: This is a test of new ticket creation + +Foob! +EOF +close (MAIL); + +# Check the return value +is ( $? >> 8, 75, "The error message above is expected The mail gateway exited with a failure. yay"); + # {{{ Test new ticket creation by root who is privileged and superuser -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: root\@localhost To: rt\@example.com @@ -45,6 +60,9 @@ Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + use RT::Tickets; my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); @@ -59,7 +77,7 @@ ok ($tick->Subject eq 'This is a test of new ticket creation', "Created the tick # {{{This is a test of new ticket creation as an unknown user -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist\@example.com To: rt\@example.com @@ -69,6 +87,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); @@ -94,7 +114,7 @@ ok ($val, "Granted everybody the right to create tickets - $msg"); sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist\@example.com To: rt\@example.com @@ -104,6 +124,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $tickets = RT::Tickets->new($RT::SystemUser); @@ -126,7 +148,7 @@ ok( $u->Id != 0, " user does not exist and was created by ticket submission"); #ok ($val, "Granted everybody the right to create tickets - $msg"); #sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-2\@example.com To: rt\@example.com @@ -136,6 +158,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $u = RT::User->new($RT::SystemUser); $u->Load('doesnotexist-2@example.com'); @@ -148,7 +172,7 @@ ok( $u->Id == 0, " user does not exist and was not created by ticket corresponde ok ($val, "Granted everybody the right to reply to tickets - $msg"); sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-2\@example.com To: rt\@example.com @@ -158,6 +182,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $u = RT::User->new($RT::SystemUser); @@ -173,7 +199,7 @@ ok( $u->Id != 0, " user exists and was created by ticket correspondence submissi #ok ($val, "Granted everybody the right to create tickets - $msg"); #sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action comment"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-3\@example.com To: rt\@example.com @@ -184,6 +210,9 @@ Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + $u = RT::User->new($RT::SystemUser); $u->Load('doesnotexist-3@example.com'); ok( $u->Id == 0, " user does not exist and was not created by ticket comment submission"); @@ -196,7 +225,7 @@ ok( $u->Id == 0, " user does not exist and was not created by ticket comment sub ok ($val, "Granted everybody the right to reply to tickets - $msg"); sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action comment"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-3\@example.com To: rt\@example.com @@ -207,6 +236,8 @@ Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $u = RT::User->new($RT::SystemUser); $u->Load('doesnotexist-3@example.com'); @@ -227,17 +258,20 @@ my $entity = MIME::Entity->build( From => 'root@localhost', Data => ['This is a test of a binary attachment']); # currently in lib/t/autogen -$entity->attach(Path => '../../../html/NoAuth/images/spacer.gif', +$entity->attach(Path => '/opt/rt3/share/html/NoAuth/images/spacer.gif', Type => 'image/gif', Encoding => 'base64'); # Create a ticket with a binary attachment -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); $entity->print(\*MAIL); close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0'); @@ -273,7 +307,7 @@ use LWP::UserAgent; # Grab the binary attachment via the web ui my $ua = LWP::UserAgent->new(); -my $full_url = "http://localhost/Ticket/Attachment/".$attachment->TransactionId."/".$attachment->id."/spacer.gif?&user=root&pass=password"; +my $full_url = "http://localhost".$RT::WebPath."/Ticket/Attachment/".$attachment->TransactionId."/".$attachment->id."/spacer.gif?&user=root&pass=password"; my $r = $ua->get( $full_url); @@ -286,7 +320,7 @@ is($file, $r->content, 'The attachment isn\'t screwed up in download'); # {{{ Simple I18N testing -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: root\@localhost @@ -301,6 +335,9 @@ bye EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + my $unitickets = RT::Tickets->new($RT::SystemUser); $unitickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $unitickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0'); @@ -317,7 +354,7 @@ is ($unitick->Transactions->First->Content, $unitick->Transactions->First->Attac ok($unitick->Transactions->First->Attachments->First->Content =~ /$unistring/i, $unitick->Id." appears to be unicode ". $unitick->Transactions->First->Attachments->First->Id); # supposedly I18N fails on the second message sent in. -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: root\@localhost @@ -332,6 +369,9 @@ bye EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + my $tickets2 = RT::Tickets->new($RT::SystemUser); $tickets2->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets2->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0'); @@ -367,7 +407,7 @@ use LWP::UserAgent; use constant EX_TEMPFAIL => 75; my %opts; -GetOptions( \%opts, "queue=s", "action=s", "url=s", "jar=s", "help", "debug", "extension=s" ); +GetOptions( \%opts, "queue=s", "action=s", "url=s", "jar=s", "help", "debug", "extension=s", "timeout=i" ); if ( $opts{help} ) { require Pod::Usage; @@ -381,17 +421,18 @@ for (qw(url)) { } undef $/; -my $message = <>; my $ua = LWP::UserAgent->new(); $ua->cookie_jar( { file => $opts{jar} } ); my %args = ( queue => $opts{queue}, action => $opts{action}, - message => $message, SessionType => 'REST', # Surpress login box ); +# Read the message in from STDIN +$args{'message'} = <>; + if ($opts{'extension'}) { $args{$opts{'extension'}} = $ENV{'EXTENSION'}; @@ -404,6 +445,7 @@ warn "Connecting to $full_url" if $opts{'debug'}; +$ua->timeout(exists($opts{'timeout'}) ? $opts{'timeout'} : 180); my $r = $ua->post( $full_url, {%args} ); check_failure($r); @@ -414,7 +456,7 @@ if ( $content !~ /^(ok|not ok)/ ) { # It's not the server's fault if the mail is bogus. We just want to know that # *something* came out of the server. - die <<EOF + warn <<EOF; RT server error. The RT server which handled your email did not behave as expected. It @@ -423,8 +465,13 @@ said: $content EOF +exit EX_TEMPFAIL; + } +exit; + + sub check_failure { my $r = shift; return if $r->is_success(); @@ -455,7 +502,11 @@ Usual invocation (from MTA): rt-mailgate --action (correspond|comment) --queue queuename --url http://your.rt.server/ - [ --extension (queue|action|ticket) + [ --debug ] + [ --extension (queue|action|ticket) ] + [ --timeout seconds ] + + See C<man rt-mailgate> for more. @@ -486,6 +537,16 @@ submitted to will be set to the value of $EXTENSION. By specifying is related to. "action" will allow the user to specify either "comment" or "correspond" in the address extension. +=item C<--debug> OPTIONAL + +Print debugging output to standard error + + +=item C<--timeout> OPTIONAL + +Configure the timeout for posting the message to the web server. The +default timeout is 3 minutes (180 seconds). + =head1 DESCRIPTION diff --git a/rt/bin/rt-mailgate.in b/rt/bin/rt-mailgate.in index 304fcbcd6..2ddb604ec 100644 --- a/rt/bin/rt-mailgate.in +++ b/rt/bin/rt-mailgate.in @@ -1,26 +1,26 @@ #!@PERL@ -w # BEGIN LICENSE BLOCK -# +# # Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> -# +# # (Except where explictly superceded by other copyright notices) -# +# # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed # from www.gnu.org. -# +# # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. -# +# # Unless otherwise specified, all modifications, corrections or # extensions to this work which alter its source code become the # property of Best Practical Solutions, LLC when submitted for # inclusion in the work. -# -# +# +# # END LICENSE BLOCK =head1 NAME @@ -31,10 +31,25 @@ rt-mailgate - Mail interface to RT3. use RT::I18N; +# Make sure that when we call the mailgate wrong, it tempfails + +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://bad.address"), "Opened the mailgate - The error below is expected - $@"); +print MAIL <<EOF; +From: root\@localhost +To: rt\@example.com +Subject: This is a test of new ticket creation + +Foob! +EOF +close (MAIL); + +# Check the return value +is ( $? >> 8, 75, "The error message above is expected The mail gateway exited with a failure. yay"); + # {{{ Test new ticket creation by root who is privileged and superuser -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: root\@localhost To: rt\@example.com @@ -45,6 +60,9 @@ Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + use RT::Tickets; my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); @@ -59,7 +77,7 @@ ok ($tick->Subject eq 'This is a test of new ticket creation', "Created the tick # {{{This is a test of new ticket creation as an unknown user -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist\@example.com To: rt\@example.com @@ -69,6 +87,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); @@ -94,7 +114,7 @@ ok ($val, "Granted everybody the right to create tickets - $msg"); sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist\@example.com To: rt\@example.com @@ -104,6 +124,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $tickets = RT::Tickets->new($RT::SystemUser); @@ -126,7 +148,7 @@ ok( $u->Id != 0, " user does not exist and was created by ticket submission"); #ok ($val, "Granted everybody the right to create tickets - $msg"); #sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-2\@example.com To: rt\@example.com @@ -136,6 +158,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $u = RT::User->new($RT::SystemUser); $u->Load('doesnotexist-2@example.com'); @@ -148,7 +172,7 @@ ok( $u->Id == 0, " user does not exist and was not created by ticket corresponde ok ($val, "Granted everybody the right to reply to tickets - $msg"); sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-2\@example.com To: rt\@example.com @@ -158,6 +182,8 @@ Blah! Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $u = RT::User->new($RT::SystemUser); @@ -173,7 +199,7 @@ ok( $u->Id != 0, " user exists and was created by ticket correspondence submissi #ok ($val, "Granted everybody the right to create tickets - $msg"); #sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action comment"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-3\@example.com To: rt\@example.com @@ -184,6 +210,9 @@ Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + $u = RT::User->new($RT::SystemUser); $u->Load('doesnotexist-3@example.com'); ok( $u->Id == 0, " user does not exist and was not created by ticket comment submission"); @@ -196,7 +225,7 @@ ok( $u->Id == 0, " user does not exist and was not created by ticket comment sub ok ($val, "Granted everybody the right to reply to tickets - $msg"); sleep(60); # gotta sleep so the remote process' ACL cache times out -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action comment"), "Opened the mailgate - $@"); print MAIL <<EOF; From: doesnotexist-3\@example.com To: rt\@example.com @@ -207,6 +236,8 @@ Foob! EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); $u = RT::User->new($RT::SystemUser); $u->Load('doesnotexist-3@example.com'); @@ -227,17 +258,20 @@ my $entity = MIME::Entity->build( From => 'root@localhost', Data => ['This is a test of a binary attachment']); # currently in lib/t/autogen -$entity->attach(Path => '../../../html/NoAuth/images/spacer.gif', +$entity->attach(Path => '@MASON_HTML_PATH@/NoAuth/images/spacer.gif', Type => 'image/gif', Encoding => 'base64'); # Create a ticket with a binary attachment -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); $entity->print(\*MAIL); close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0'); @@ -273,7 +307,7 @@ use LWP::UserAgent; # Grab the binary attachment via the web ui my $ua = LWP::UserAgent->new(); -my $full_url = "http://localhost/Ticket/Attachment/".$attachment->TransactionId."/".$attachment->id."/spacer.gif?&user=root&pass=password"; +my $full_url = "http://localhost".$RT::WebPath."/Ticket/Attachment/".$attachment->TransactionId."/".$attachment->id."/spacer.gif?&user=root&pass=password"; my $r = $ua->get( $full_url); @@ -286,7 +320,7 @@ is($file, $r->content, 'The attachment isn\'t screwed up in download'); # {{{ Simple I18N testing -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: root\@localhost @@ -301,6 +335,9 @@ bye EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + my $unitickets = RT::Tickets->new($RT::SystemUser); $unitickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $unitickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0'); @@ -317,7 +354,7 @@ is ($unitick->Transactions->First->Content, $unitick->Transactions->First->Attac ok($unitick->Transactions->First->Attachments->First->Content =~ /$unistring/i, $unitick->Id." appears to be unicode ". $unitick->Transactions->First->Attachments->First->Id); # supposedly I18N fails on the second message sent in. -ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@"); +ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); print MAIL <<EOF; From: root\@localhost @@ -332,6 +369,9 @@ bye EOF close (MAIL); +#Check the return value +is ($? >> 8, 0, "The mail gateway exited normally. yay"); + my $tickets2 = RT::Tickets->new($RT::SystemUser); $tickets2->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets2->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0'); @@ -367,7 +407,7 @@ use LWP::UserAgent; use constant EX_TEMPFAIL => 75; my %opts; -GetOptions( \%opts, "queue=s", "action=s", "url=s", "jar=s", "help", "debug", "extension=s" ); +GetOptions( \%opts, "queue=s", "action=s", "url=s", "jar=s", "help", "debug", "extension=s", "timeout=i" ); if ( $opts{help} ) { require Pod::Usage; @@ -381,17 +421,18 @@ for (qw(url)) { } undef $/; -my $message = <>; my $ua = LWP::UserAgent->new(); $ua->cookie_jar( { file => $opts{jar} } ); my %args = ( queue => $opts{queue}, action => $opts{action}, - message => $message, SessionType => 'REST', # Surpress login box ); +# Read the message in from STDIN +$args{'message'} = <>; + if ($opts{'extension'}) { $args{$opts{'extension'}} = $ENV{'EXTENSION'}; @@ -404,6 +445,7 @@ warn "Connecting to $full_url" if $opts{'debug'}; +$ua->timeout(exists($opts{'timeout'}) ? $opts{'timeout'} : 180); my $r = $ua->post( $full_url, {%args} ); check_failure($r); @@ -414,7 +456,7 @@ if ( $content !~ /^(ok|not ok)/ ) { # It's not the server's fault if the mail is bogus. We just want to know that # *something* came out of the server. - die <<EOF + warn <<EOF; RT server error. The RT server which handled your email did not behave as expected. It @@ -423,8 +465,13 @@ said: $content EOF +exit EX_TEMPFAIL; + } +exit; + + sub check_failure { my $r = shift; return if $r->is_success(); @@ -455,7 +502,11 @@ Usual invocation (from MTA): rt-mailgate --action (correspond|comment) --queue queuename --url http://your.rt.server/ - [ --extension (queue|action|ticket) + [ --debug ] + [ --extension (queue|action|ticket) ] + [ --timeout seconds ] + + See C<man rt-mailgate> for more. @@ -486,6 +537,16 @@ submitted to will be set to the value of $EXTENSION. By specifying is related to. "action" will allow the user to specify either "comment" or "correspond" in the address extension. +=item C<--debug> OPTIONAL + +Print debugging output to standard error + + +=item C<--timeout> OPTIONAL + +Configure the timeout for posting the message to the web server. The +default timeout is 3 minutes (180 seconds). + =head1 DESCRIPTION diff --git a/rt/bin/rt.in b/rt/bin/rt.in new file mode 100644 index 000000000..90369b5b3 --- /dev/null +++ b/rt/bin/rt.in @@ -0,0 +1,1816 @@ +#!@PERL@ -w +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK + +use strict; + +# This program is intentionally written to have as few non-core module +# dependencies as possible. It should stay that way. + +use Cwd; +use LWP; +use HTTP::Request::Common; + +# We derive configuration information from hardwired defaults, dotfiles, +# and the RT* environment variables (in increasing order of precedence). +# Session information is stored in ~/.rt_sessions. + +my $VERSION = 0.02; +my $HOME = eval{(getpwuid($<))[7]} + || $ENV{HOME} || $ENV{LOGDIR} || $ENV{HOMEPATH} + || "."; +my %config = ( + ( + debug => 0, + user => eval{(getpwuid($<))[0]} || $ENV{USER} || $ENV{USERNAME}, + passwd => undef, + server => 'http://localhost/rt/', + ), + config_from_file($ENV{RTCONFIG} || ".rtrc"), + config_from_env() +); +my $session = new Session("$HOME/.rt_sessions"); +my $REST = "$config{server}/REST/1.0"; + +sub whine; +sub DEBUG { warn @_ if $config{debug} >= shift } + +# These regexes are used by command handlers to parse arguments. +# (XXX: Ask Autrijus how i18n changes these definitions.) + +my $name = '[\w.-]+'; +my $field = '[a-zA-Z][a-zA-Z0-9_-]*'; +my $label = '[a-zA-Z0-9@_.+-]+'; +my $labels = "(?:$label,)*$label"; +my $idlist = '(?:(?:\d+-)?\d+,)*(?:\d+-)?\d+'; + +# Our command line looks like this: +# +# rt <action> [options] [arguments] +# +# We'll parse just enough of it to decide upon an action to perform, and +# leave the rest to per-action handlers to interpret appropriately. + +my %handlers = ( +# handler => [ ...aliases... ], + version => ["version", "ver"], + logout => ["logout"], + help => ["help", "man"], + show => ["show", "cat"], + edit => ["create", "edit", "new", "ed"], + list => ["search", "list", "ls"], + comment => ["comment", "correspond"], + link => ["link", "ln"], + merge => ["merge"], + grant => ["grant", "revoke"], +); + +# Once we find and call an appropriate handler, we're done. + +my (%actions, $action); +foreach my $fn (keys %handlers) { + foreach my $alias (@{ $handlers{$fn} }) { + $actions{$alias} = \&{"$fn"}; + } +} +if (@ARGV && exists $actions{$ARGV[0]}) { + $action = shift @ARGV; +} +$actions{$action || "help"}->($action || ()); +exit; + +# Handler functions. +# ------------------ +# +# The following subs are handlers for each entry in %actions. + +sub version { + print "rt $VERSION\n"; +} + +sub logout { + submit("$REST/logout") if defined $session->cookie; +} + +sub help { + my ($action, $type) = @_; + my (%help, $key); + + # What help topics do we know about? + local $/ = undef; + foreach my $item (@{ Form::parse(<DATA>) }) { + my $title = $item->[2]{Title}; + my @titles = ref $title eq 'ARRAY' ? @$title : $title; + + foreach $title (grep $_, @titles) { + $help{$title} = $item->[2]{Text}; + } + } + + # What does the user want help with? + undef $action if ($action && $actions{$action} eq \&help); + unless ($action || $type) { + # If we don't know, we'll look for clues in @ARGV. + foreach (@ARGV) { + if (exists $help{$_}) { $key = $_; last; } + } + unless ($key) { + # Tolerate possibly plural words. + foreach (@ARGV) { + if ($_ =~ s/s$// && exists $help{$_}) { $key = $_; last; } + } + } + } + + if ($type && $action) { + $key = "$type.$action"; + } + $key ||= $type || $action || "introduction"; + + # Find a suitable topic to display. + while (!exists $help{$key}) { + if ($type && $action) { + if ($key eq "$type.$action") { $key = $action; } + elsif ($key eq $action) { $key = $type; } + else { $key = "introduction"; } + } + else { + $key = "introduction"; + } + } + + print STDERR $help{$key}, "\n\n"; +} + +# Displays a list of objects that match some specified condition. + +sub list { + my ($q, $type, %data, $orderby); + my $bad = 0; + + while (@ARGV) { + $_ = shift @ARGV; + + if (/^-t$/) { + $bad = 1, last unless defined($type = get_type_argument()); + } + elsif (/^-S$/) { + $bad = 1, last unless get_var_argument(\%data); + } + elsif (/^-o$/) { + $orderby = shift @ARGV; + } + elsif (/^-([isl])$/) { + $data{format} = $1; + } + elsif (/^-f$/) { + if ($ARGV[0] !~ /^(?:(?:$field,)*$field)$/) { + whine "No valid field list in '-f $ARGV[0]'."; + $bad = 1; last; + } + $data{fields} = shift @ARGV; + } + elsif (!defined $q && !/^-/) { + $q = $_; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } + + $type ||= "ticket"; + unless ($type && defined $q) { + my $item = $type ? "query string" : "object type"; + whine "No $item specified."; + $bad = 1; + } + return help("list", $type) if $bad; + + my $r = submit("$REST/search/$type", { query => $q, %data, orderby => $orderby || "" }); + print $r->content; +} + +# Displays selected information about a single object. + +sub show { + my ($type, @objects, %data); + my $slurped = 0; + my $bad = 0; + + while (@ARGV) { + $_ = shift @ARGV; + + if (/^-t$/) { + $bad = 1, last unless defined($type = get_type_argument()); + } + elsif (/^-S$/) { + $bad = 1, last unless get_var_argument(\%data); + } + elsif (/^-([isl])$/) { + $data{format} = $1; + } + elsif (/^-$/ && !$slurped) { + chomp(my @lines = <STDIN>); + foreach (@lines) { + unless (is_object_spec($_, $type)) { + whine "Invalid object on STDIN: '$_'."; + $bad = 1; last; + } + push @objects, $_; + } + $slurped = 1; + } + elsif (/^-f$/) { + if ($ARGV[0] !~ /^(?:(?:$field,)*$field)$/) { + whine "No valid field list in '-f $ARGV[0]'."; + $bad = 1; last; + } + $data{fields} = shift @ARGV; + } + elsif (my $spec = is_object_spec($_, $type)) { + push @objects, $spec; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } + + unless (@objects) { + whine "No objects specified."; + $bad = 1; + } + return help("show", $type) if $bad; + + my $r = submit("$REST/show", { id => \@objects, %data }); + print $r->content; +} + +# To create a new object, we ask the server for a form with the defaults +# filled in, allow the user to edit it, and send the form back. +# +# To edit an object, we must ask the server for a form representing that +# object, make changes requested by the user (either on the command line +# or interactively via $EDITOR), and send the form back. + +sub edit { + my ($action) = @_; + my (%data, $type, @objects); + my ($cl, $text, $edit, $input, $output); + + use vars qw(%set %add %del); + %set = %add = %del = (); + my $slurped = 0; + my $bad = 0; + + while (@ARGV) { + $_ = shift @ARGV; + + if (/^-e$/) { $edit = 1 } + elsif (/^-i$/) { $input = 1 } + elsif (/^-o$/) { $output = 1 } + elsif (/^-t$/) { + $bad = 1, last unless defined($type = get_type_argument()); + } + elsif (/^-S$/) { + $bad = 1, last unless get_var_argument(\%data); + } + elsif (/^-$/ && !($slurped || $input)) { + chomp(my @lines = <STDIN>); + foreach (@lines) { + unless (is_object_spec($_, $type)) { + whine "Invalid object on STDIN: '$_'."; + $bad = 1; last; + } + push @objects, $_; + } + $slurped = 1; + } + elsif (/^set$/i) { + my $vars = 0; + + while (@ARGV && $ARGV[0] =~ /^($field)([+-]?=)(.*)$/) { + my ($key, $op, $val) = ($1, $2, $3); + my $hash = ($op eq '=') ? \%set : ($op =~ /^\+/) ? \%add : \%del; + + vpush($hash, lc $key, $val); + shift @ARGV; + $vars++; + } + unless ($vars) { + whine "No variables to set."; + $bad = 1; last; + } + $cl = $vars; + } + elsif (/^(?:add|del)$/i) { + my $vars = 0; + my $hash = ($_ eq "add") ? \%add : \%del; + + while (@ARGV && $ARGV[0] =~ /^($field)=(.*)$/) { + my ($key, $val) = ($1, $2); + + vpush($hash, lc $key, $val); + shift @ARGV; + $vars++; + } + unless ($vars) { + whine "No variables to set."; + $bad = 1; last; + } + $cl = $vars; + } + elsif (my $spec = is_object_spec($_, $type)) { + push @objects, $spec; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } + + if ($action =~ /^ed(?:it)?$/) { + unless (@objects) { + whine "No objects specified."; + $bad = 1; + } + } + else { + if (@objects) { + whine "You shouldn't specify objects as arguments to $action."; + $bad = 1; + } + unless ($type) { + whine "What type of object do you want to create?"; + $bad = 1; + } + @objects = ("$type/new"); + } + return help($action, $type) if $bad; + + # We need a form to make changes to. We usually ask the server for + # one, but we can avoid that if we are fed one on STDIN, or if the + # user doesn't want to edit the form by hand, and the command line + # specifies only simple variable assignments. + + if ($input) { + local $/ = undef; + $text = <STDIN>; + } + elsif ($edit || %add || %del || !$cl) { + my $r = submit("$REST/show", { id => \@objects, format => 'l' }); + $text = $r->content; + } + + # If any changes were specified on the command line, apply them. + if ($cl) { + if ($text) { + # We're updating forms from the server. + my $forms = Form::parse($text); + + foreach my $form (@$forms) { + my ($c, $o, $k, $e) = @$form; + my ($key, $val); + + next if ($e || !@$o); + + local %add = %add; + local %del = %del; + local %set = %set; + + # Make changes to existing fields. + foreach $key (@$o) { + if (exists $add{lc $key}) { + $val = delete $add{lc $key}; + vpush($k, $key, $val); + $k->{$key} = vsplit($k->{$key}) if $val =~ /[,\n]/; + } + if (exists $del{lc $key}) { + $val = delete $del{lc $key}; + my %val = map {$_=>1} @{ vsplit($val) }; + $k->{$key} = vsplit($k->{$key}); + @{$k->{$key}} = grep {!exists $val{$_}} @{$k->{$key}}; + } + if (exists $set{lc $key}) { + $k->{$key} = delete $set{lc $key}; + } + } + + # Then update the others. + foreach $key (keys %set) { vpush($k, $key, $set{$key}) } + foreach $key (keys %add) { + vpush($k, $key, $add{$key}); + $k->{$key} = vsplit($k->{$key}); + } + push @$o, (keys %add, keys %set); + } + + $text = Form::compose($forms); + } + else { + # We're rolling our own set of forms. + my @forms; + foreach (@objects) { + my ($type, $ids, $args) = + m{^($name)/($idlist|$labels)(?:(/.*))?$}o; + + $args ||= ""; + foreach my $obj (expand_list($ids)) { + my %set = (%set, id => "$type/$obj$args"); + push @forms, ["", [keys %set], \%set]; + } + } + $text = Form::compose(\@forms); + } + } + + if ($output) { + print $text; + exit; + } + + my $synerr = 0; + +EDIT: + # We'll let the user edit the form before sending it to the server, + # unless we have enough information to submit it non-interactively. + if ($edit || (!$input && !$cl)) { + my $newtext = vi($text); + # We won't resubmit a bad form unless it was changed. + $text = ($synerr && $newtext eq $text) ? undef : $newtext; + } + + if ($text) { + my $r = submit("$REST/edit", {content => $text, %data}); + if ($r->code == 409) { + # If we submitted a bad form, we'll give the user a chance + # to correct it and resubmit. + if ($edit || (!$input && !$cl)) { + $text = $r->content; + $synerr = 1; + goto EDIT; + } + else { + print $r->content; + exit -1; + } + } + print $r->content; + } +} + +# We roll "comment" and "correspond" into the same handler. + +sub comment { + my ($action) = @_; + my (%data, $id, @files, @bcc, @cc, $msg, $wtime, $edit); + my $bad = 0; + + while (@ARGV) { + $_ = shift @ARGV; + + if (/^-e$/) { + $edit = 1; + } + elsif (/^-[abcmw]$/) { + unless (@ARGV) { + whine "No argument specified with $_."; + $bad = 1; last; + } + + if (/-a/) { + unless (-f $ARGV[0] && -r $ARGV[0]) { + whine "Cannot read attachment: '$ARGV[0]'."; + exit -1; + } + push @files, shift @ARGV; + } + elsif (/-([bc])/) { + my $a = $_ eq "-b" ? \@bcc : \@cc; + @$a = split /\s*,\s*/, shift @ARGV; + } + elsif (/-m/) { $msg = shift @ARGV } + elsif (/-w/) { $wtime = shift @ARGV } + } + elsif (!$id && m|^(?:ticket/)?($idlist)$|) { + $id = $1; + } + else { + my $datum = /^-/ ? "option" : "argument"; + whine "Unrecognised $datum '$_'."; + $bad = 1; last; + } + } + + unless ($id) { + whine "No object specified."; + $bad = 1; + } + return help($action, "ticket") if $bad; + + my $form = [ + "", + [ "Ticket", "Action", "Cc", "Bcc", "Attachment", "TimeWorked", "Text" ], + { + Ticket => $id, + Action => $action, + Cc => [ @cc ], + Bcc => [ @bcc ], + Attachment => [ @files ], + TimeWorked => $wtime || '', + Text => $msg || '', + } + ]; + + my $text = Form::compose([ $form ]); + + if ($edit || !$msg) { + my $error = 0; + my ($c, $o, $k, $e); + + do { + my $ntext = vi($text); + exit if ($error && $ntext eq $text); + $text = $ntext; + $form = Form::parse($text); + $error = 0; + + ($c, $o, $k, $e) = @{ $form->[0] }; + if ($e) { + $error = 1; + $c = "# Syntax error."; + goto NEXT; + } + elsif (!@$o) { + exit; + } + @files = @{ vsplit($k->{Attachment}) }; + + NEXT: + $text = Form::compose([[$c, $o, $k, $e]]); + } while ($error); + } + + my $i = 1; + foreach my $file (@files) { + $data{"attachment_$i"} = bless([ $file ], "Attachment"); + $i++; + } + $data{content} = $text; + + my $r = submit("$REST/ticket/comment/$id", \%data); + print $r->content; +} + +# Merge one ticket into another. + +sub merge { + my @id; + my $bad = 0; + + while (@ARGV) { + $_ = shift @ARGV; + + if (/^\d+$/) { + push @id, $_; + } + else { + whine "Unrecognised argument: '$_'."; + $bad = 1; last; + } + } + + unless (@id == 2) { + my $evil = @id > 2 ? "many" : "few"; + whine "Too $evil arguments specified."; + $bad = 1; + } + return help("merge", "ticket") if $bad; + + my $r = submit("$REST/ticket/merge/$id[0]", {into => $id[1]}); + print $r->content; +} + +# Link one ticket to another. + +sub link { + my ($bad, $del, %data) = (0, 0, ()); + my %ltypes = map { lc $_ => $_ } qw(DependsOn DependedOnBy RefersTo + ReferredToBy HasMember MemberOf); + + while (@ARGV && $ARGV[0] =~ /^-/) { + $_ = shift @ARGV; + + if (/^-d$/) { + $del = 1; + } + else { + whine "Unrecognised option: '$_'."; + $bad = 1; last; + } + } + + if (@ARGV == 3) { + my ($from, $rel, $to) = @ARGV; + if ($from !~ /^\d+$/ || $to !~ /^\d+$/) { + my $bad = $from =~ /^\d+$/ ? $to : $from; + whine "Invalid ticket ID '$bad' specified."; + $bad = 1; + } + unless (exists $ltypes{lc $rel}) { + whine "Invalid relationship '$rel' specified."; + $bad = 1; + } + %data = (id => $from, rel => $rel, to => $to, del => $del); + } + else { + my $bad = @ARGV < 3 ? "few" : "many"; + whine "Too $bad arguments specified."; + $bad = 1; + } + return help("link", "ticket") if $bad; + + my $r = submit("$REST/ticket/link", \%data); + print $r->content; +} + +# Grant/revoke a user's rights. + +sub grant { + my ($cmd) = @_; + + my $revoke = 0; + while (@ARGV) { + } + + $revoke = 1 if $cmd->{action} eq 'revoke'; +} + +# Client <-> Server communication. +# -------------------------------- +# +# This function composes and sends an HTTP request to the RT server, and +# interprets the response. It takes a request URI, and optional request +# data (a string, or a reference to a set of key-value pairs). + +sub submit { + my ($uri, $content) = @_; + my ($req, $data); + my $ua = new LWP::UserAgent(agent => "RT/3.0b", env_proxy => 1); + + # Did the caller specify any data to send with the request? + $data = []; + if (defined $content) { + unless (ref $content) { + # If it's just a string, make sure LWP handles it properly. + # (By pretending that it's a file!) + $content = [ content => [undef, "", Content => $content] ]; + } + elsif (ref $content eq 'HASH') { + my @data; + foreach my $k (keys %$content) { + if (ref $content->{$k} eq 'ARRAY') { + foreach my $v (@{ $content->{$k} }) { + push @data, $k, $v; + } + } + else { push @data, $k, $content->{$k} } + } + $content = \@data; + } + $data = $content; + } + + # Should we send authentication information to start a new session? + if (!defined $session->cookie) { + push @$data, ( user => $config{user} ); + push @$data, ( pass => $config{passwd} || read_passwd() ); + } + + # Now, we construct the request. + if (@$data) { + $req = POST($uri, $data, Content_Type => 'form-data'); + } + else { + $req = GET($uri); + } + $session->add_cookie_header($req); + + # Then we send the request and parse the response. + DEBUG(3, $req->as_string); + my $res = $ua->request($req); + DEBUG(3, $res->as_string); + + if ($res->is_success) { + # The content of the response we get from the RT server consists + # of an HTTP-like status line followed by optional header lines, + # a blank line, and arbitrary text. + + my ($head, $text) = split /\n\n/, $res->content, 2; + my ($status, @headers) = split /\n/, $head; + $text =~ s/\n*$/\n/; + + # "RT/3.0.1 401 Credentials required" + if ($status !~ m#^RT/\d+(?:\.\d+)+(?:-?\w+)? (\d+) ([\w\s]+)$#) { + warn "rt: Malformed RT response from $config{server}.\n"; + warn "(Rerun with RTDEBUG=3 for details.)\n" if $config{debug} < 3; + exit -1; + } + + # Our caller can pretend that the server returned a custom HTTP + # response code and message. (Doing that directly is apparently + # not sufficiently portable and uncomplicated.) + $res->code($1); + $res->message($2); + $res->content($text); + $session->update($res) if ($res->is_success || $res->code != 401); + + if (!$res->is_success) { + # We can deal with authentication failures ourselves. Either + # we sent invalid credentials, or our session has expired. + if ($res->code == 401) { + my %d = @$data; + if (exists $d{user}) { + warn "rt: Incorrect username or password.\n"; + exit -1; + } + elsif ($req->header("Cookie")) { + # We'll retry the request with credentials, unless + # we only wanted to logout in the first place. + $session->delete; + return submit(@_) unless $uri eq "$REST/logout"; + } + } + # Conflicts should be dealt with by the handler and user. + # For anything else, we just die. + elsif ($res->code != 409) { + warn "rt: ", $res->content; + exit; + } + } + } + else { + warn "rt: Server error: ", $res->message, " (", $res->code, ")\n"; + exit -1; + } + + return $res; +} + +# Session management. +# ------------------- +# +# Maintains a list of active sessions in the ~/.rt_sessions file. +{ + package Session; + my ($s, $u); + + # Initialises the session cache. + sub new { + my ($class, $file) = @_; + my $self = { + file => $file || "$HOME/.rt_sessions", + sids => { } + }; + + # The current session is identified by the currently configured + # server and user. + ($s, $u) = @config{"server", "user"}; + + bless $self, $class; + $self->load(); + + return $self; + } + + # Returns the current session cookie. + sub cookie { + my ($self) = @_; + my $cookie = $self->{sids}{$s}{$u}; + return defined $cookie ? "RT_SID=$cookie" : undef; + } + + # Deletes the current session cookie. + sub delete { + my ($self) = @_; + delete $self->{sids}{$s}{$u}; + } + + # Adds a Cookie header to an outgoing HTTP request. + sub add_cookie_header { + my ($self, $request) = @_; + my $cookie = $self->cookie(); + + $request->header(Cookie => $cookie) if defined $cookie; + } + + # Extracts the Set-Cookie header from an HTTP response, and updates + # session information accordingly. + sub update { + my ($self, $response) = @_; + my $cookie = $response->header("Set-Cookie"); + + if (defined $cookie && $cookie =~ /^RT_SID=([0-9A-Fa-f]+);/) { + $self->{sids}{$s}{$u} = $1; + } + } + + # Loads the session cache from the specified file. + sub load { + my ($self, $file) = @_; + $file ||= $self->{file}; + local *F; + + open(F, $file) && do { + $self->{file} = $file; + my $sids = $self->{sids} = {}; + while (<F>) { + chomp; + next if /^$/ || /^#/; + next unless m#^https?://[^ ]+ \w+ [0-9A-Fa-f]+$#; + my ($server, $user, $cookie) = split / /, $_; + $sids->{$server}{$user} = $cookie; + } + return 1; + }; + return 0; + } + + # Writes the current session cache to the specified file. + sub save { + my ($self, $file) = shift; + $file ||= $self->{file}; + local *F; + + open(F, ">$file") && do { + my $sids = $self->{sids}; + foreach my $server (keys %$sids) { + foreach my $user (keys %{ $sids->{$server} }) { + my $sid = $sids->{$server}{$user}; + if (defined $sid) { + print F "$server $user $sid\n"; + } + } + } + close(F); + chmod 0600, $file; + return 1; + }; + return 0; + } + + sub DESTROY { + my $self = shift; + $self->save; + } +} + +# Form handling. +# -------------- +# +# Forms are RFC822-style sets of (field, value) specifications with some +# initial comments and interspersed blank lines allowed for convenience. +# Sets of forms are separated by --\n (in a cheap parody of MIME). +# +# Each form is parsed into an array with four elements: commented text +# at the start of the form, an array with the order of keys, a hash with +# key/value pairs, and optional error text if the form syntax was wrong. + +# Returns a reference to an array of parsed forms. +sub Form::parse { + my $state = 0; + my @forms = (); + my @lines = split /\n/, $_[0]; + my ($c, $o, $k, $e) = ("", [], {}, ""); + + LINE: + while (@lines) { + my $line = shift @lines; + + next LINE if $line eq ''; + + if ($line eq '--') { + # We reached the end of one form. We'll ignore it if it was + # empty, and store it otherwise, errors and all. + if ($e || $c || @$o) { + push @forms, [ $c, $o, $k, $e ]; + $c = ""; $o = []; $k = {}; $e = ""; + } + $state = 0; + } + elsif ($state != -1) { + if ($state == 0 && $line =~ /^#/) { + # Read an optional block of comments (only) at the start + # of the form. + $state = 1; + $c = $line; + while (@lines && $lines[0] =~ /^#/) { + $c .= "\n".shift @lines; + } + $c .= "\n"; + } + elsif ($state <= 1 && $line =~ /^($field):(?:\s+(.*))?$/) { + # Read a field: value specification. + my $f = $1; + my @v = ($2 || ()); + + # Read continuation lines, if any. + while (@lines && ($lines[0] eq '' || $lines[0] =~ /^\s+/)) { + push @v, shift @lines; + } + pop @v while (@v && $v[-1] eq ''); + + # Strip longest common leading indent from text. + my $ws = ""; + foreach my $ls (map {/^(\s+)/} @v[1..$#v]) { + $ws = $ls if (!$ws || length($ls) < length($ws)); + } + s/^$ws// foreach @v; + + push(@$o, $f) unless exists $k->{$f}; + vpush($k, $f, join("\n", @v)); + + $state = 1; + } + elsif ($line !~ /^#/) { + # We've found a syntax error, so we'll reconstruct the + # form parsed thus far, and add an error marker. (>>) + $state = -1; + $e = Form::compose([[ "", $o, $k, "" ]]); + $e.= $line =~ /^>>/ ? "$line\n" : ">> $line\n"; + } + } + else { + # We saw a syntax error earlier, so we'll accumulate the + # contents of this form until the end. + $e .= "$line\n"; + } + } + push(@forms, [ $c, $o, $k, $e ]) if ($e || $c || @$o); + + foreach my $l (keys %$k) { + $k->{$l} = vsplit($k->{$l}) if (ref $k->{$l} eq 'ARRAY'); + } + + return \@forms; +} + +# Returns text representing a set of forms. +sub Form::compose { + my ($forms) = @_; + my @text; + + foreach my $form (@$forms) { + my ($c, $o, $k, $e) = @$form; + my $text = ""; + + if ($c) { + $c =~ s/\n*$/\n/; + $text = "$c\n"; + } + if ($e) { + $text .= $e; + } + elsif ($o) { + my @lines; + + foreach my $key (@$o) { + my ($line, $sp); + my $v = $k->{$key}; + my @values = ref $v eq 'ARRAY' ? @$v : $v; + + $sp = " "x(length("$key: ")); + $sp = " "x4 if length($sp) > 16; + + foreach $v (@values) { + if ($v =~ /\n/) { + $v =~ s/^/$sp/gm; + $v =~ s/^$sp//; + + if ($line) { + push @lines, "$line\n\n"; + $line = ""; + } + elsif (@lines && $lines[-1] !~ /\n\n$/) { + $lines[-1] .= "\n"; + } + push @lines, "$key: $v\n\n"; + } + elsif ($line && + length($line)+length($v)-rindex($line, "\n") >= 70) + { + $line .= ",\n$sp$v"; + } + else { + $line = $line ? "$line, $v" : "$key: $v"; + } + } + + $line = "$key:" unless @values; + if ($line) { + if ($line =~ /\n/) { + if (@lines && $lines[-1] !~ /\n\n$/) { + $lines[-1] .= "\n"; + } + $line .= "\n"; + } + push @lines, "$line\n"; + } + } + + $text .= join "", @lines; + } + else { + chomp $text; + } + push @text, $text; + } + + return join "\n--\n\n", @text; +} + +# Configuration. +# -------------- + +# Returns configuration information from the environment. +sub config_from_env { + my %env; + + foreach my $k ("DEBUG", "USER", "PASSWD", "SERVER") { + if (exists $ENV{"RT$k"}) { + $env{lc $k} = $ENV{"RT$k"}; + } + } + + return %env; +} + +# Finds a suitable configuration file and returns information from it. +sub config_from_file { + my ($rc) = @_; + + if ($rc =~ m#^/#) { + # We'll use an absolute path if we were given one. + return parse_config_file($rc); + } + else { + # Otherwise we'll use the first file we can find in the current + # directory, or in one of its (increasingly distant) ancestors. + + my @dirs = split /\//, cwd; + while (@dirs) { + my $file = join('/', @dirs, $rc); + if (-r $file) { + return parse_config_file($file); + } + + # Remove the last directory component each time. + pop @dirs; + } + + # Still nothing? We'll fall back to some likely defaults. + for ("$HOME/$rc", "/etc/rt.conf") { + return parse_config_file($_) if (-r $_); + } + } + + return (); +} + +# Makes a hash of the specified configuration file. +sub parse_config_file { + my %cfg; + my ($file) = @_; + + open(CFG, $file) && do { + while (<CFG>) { + chomp; + next if (/^#/ || /^\s*$/); + + if (/^(user|passwd|server)\s+([^ ]+)$/) { + $cfg{$1} = $2; + } + else { + die "rt: $file:$.: unknown configuration directive.\n"; + } + } + }; + + return %cfg; +} + +# Helper functions. +# ----------------- + +sub whine { + my $sub = (caller(1))[3]; + $sub =~ s/^main:://; + warn "rt: $sub: @_\n"; + return; +} + +sub read_passwd { + eval 'require Term::ReadKey'; + if ($@) { + die "No password specified (and Term::ReadKey not installed).\n"; + } + + print "Password: "; + Term::ReadKey::ReadMode('noecho'); + chomp(my $passwd = Term::ReadKey::ReadLine(0)); + Term::ReadKey::ReadMode('restore'); + print "\n"; + + return $passwd; +} + +sub vi { + my ($text) = @_; + my $file = "/tmp/rt.form.$$"; + my $editor = $ENV{EDITOR} || $ENV{VISUAL} || "vi"; + + local *F; + local $/ = undef; + + open(F, ">$file") || die "$file: $!\n"; print F $text; close(F); + system($editor, $file) && die "Couldn't run $editor.\n"; + open(F, $file) || die "$file: $!\n"; $text = <F>; close(F); + unlink($file); + + return $text; +} + +# Add a value to a (possibly multi-valued) hash key. +sub vpush { + my ($hash, $key, $val) = @_; + my @val = ref $val eq 'ARRAY' ? @$val : $val; + + if (exists $hash->{$key}) { + unless (ref $hash->{$key} eq 'ARRAY') { + my @v = $hash->{$key} ne '' ? $hash->{$key} : (); + $hash->{$key} = \@v; + } + push @{ $hash->{$key} }, @val; + } + else { + $hash->{$key} = $val; + } +} + +# "Normalise" a hash key that's known to be multi-valued. +sub vsplit { + my ($val) = @_; + my ($word, @words); + my @values = ref $val eq 'ARRAY' ? @$val : $val; + + foreach my $line (map {split /\n/} @values) { + # XXX: This should become a real parser, à la Text::ParseWords. + $line =~ s/^\s+//; + $line =~ s/\s+$//; + push @words, split /\s*,\s*/, $line; + } + + return \@words; +} + +sub expand_list { + my ($list) = @_; + my ($elt, @elts, %elts); + + foreach $elt (split /,/, $list) { + if ($elt =~ /^(\d+)-(\d+)$/) { push @elts, ($1..$2) } + else { push @elts, $elt } + } + + @elts{@elts}=(); + return sort {$a<=>$b} keys %elts; +} + +sub get_type_argument { + my $type; + + if (@ARGV) { + $type = shift @ARGV; + unless ($type =~ /^[A-Za-z0-9_.-]+$/) { + # We want whine to mention our caller, not us. + @_ = ("Invalid type '$type' specified."); + goto &whine; + } + } + else { + @_ = ("No type argument specified with -t."); + goto &whine; + } + + $type =~ s/s$//; # "Plural". Ugh. + return $type; +} + +sub get_var_argument { + my ($data) = @_; + + if (@ARGV) { + my $kv = shift @ARGV; + if (my ($k, $v) = $kv =~ /^($field)=(.*)$/) { + push @{ $data->{$k} }, $v; + } + else { + @_ = ("Invalid variable specification: '$kv'."); + goto &whine; + } + } + else { + @_ = ("No variable argument specified with -S."); + goto &whine; + } +} + +sub is_object_spec { + my ($spec, $type) = @_; + + $spec =~ s|^(?:$type/)?|$type/| if defined $type; + return $spec if ($spec =~ m{^$name/(?:$idlist|$labels)(?:/.*)?$}o); + return; +} + +__DATA__ + +Title: intro +Title: introduction +Text: + + ** THIS IS AN UNSUPPORTED PREVIEW RELEASE ** + ** PLEASE REPORT BUGS TO rt-bugs@fsck.com ** + + This is a command-line interface to RT 3. + + It allows you to interact with an RT server over HTTP, and offers an + interface to RT's functionality that is better-suited to automation + and integration with other tools. + + In general, each invocation of this program should specify an action + to perform on one or more objects, and any other arguments required + to complete the desired action. + + For more information: + + - rt help actions (a list of possible actions) + - rt help objects (how to specify objects) + - rt help usage (syntax information) + + - rt help config (configuration details) + - rt help examples (a few useful examples) + - rt help topics (a list of help topics) + +-- + +Title: usage +Title: syntax +Text: + + Syntax: + + rt <action> [options] [arguments] + + Each invocation of this program must specify an action (e.g. "edit", + "create"), options to modify behaviour, and other arguments required + by the specified action. (For example, most actions expect a list of + numeric object IDs to act upon.) + + The details of the syntax and arguments for each action are given by + "rt help <action>". Some actions may be referred to by more than one + name ("create" is the same as "new", for example). + + Objects are identified by a type and an ID (which can be a name or a + number, depending on the type). For some actions, the object type is + implied (you can only comment on tickets); for others, the user must + specify it explicitly. See "rt help objects" for details. + + In syntax descriptions, mandatory arguments that must be replaced by + appropriate value are enclosed in <>, and optional arguments are + indicated by [] (for example, <action> and [options] above). + + For more information: + + - rt help objects (how to specify objects) + - rt help actions (a list of actions) + - rt help types (a list of object types) + +-- + +Title: conf +Title: config +Title: configuration +Text: + + This program has two major sources of configuration information: its + configuration files, and the environment. + + The program looks for configuration directives in a file named .rtrc + (or $RTCONFIG; see below) in the current directory, and then in more + distant ancestors, until it reaches /. If no suitable configuration + files are found, it will also check for ~/.rtrc and /etc/rt.conf. + + Configuration directives: + + The following directives may occur, one per line: + + - server <URL> URL to RT server. + - user <username> RT username. + - passwd <passwd> RT user's password. + + Blank and #-commented lines are ignored. + + Environment variables: + + The following environment variables override any corresponding + values defined in configuration files: + + - RTUSER + - RTPASSWD + - RTSERVER + - RTDEBUG Numeric debug level. (Set to 3 for full logs.) + - RTCONFIG Specifies a name other than ".rtrc" for the + configuration file. + +-- + +Title: objects +Text: + + Syntax: + + <type>/<id>[/<attributes>] + + Every object in RT has a type (e.g. "ticket", "queue") and a numeric + ID. Some types of objects can also be identified by name (like users + and queues). Furthermore, objects may have named attributes (such as + "ticket/1/history"). + + An object specification is like a path in a virtual filesystem, with + object types as top-level directories, object IDs as subdirectories, + and named attributes as further subdirectories. + + A comma-separated list of names, numeric IDs, or numeric ranges can + be used to specify more than one object of the same type. Note that + the list must be a single argument (i.e., no spaces). For example, + "user/root,1-3,5,7-10,ams" is a list of ten users; the same list + can also be written as "user/ams,root,1,2,3,5,7,8-20". + + Examples: + + ticket/1 + ticket/1/attachments + ticket/1/attachments/3 + ticket/1/attachments/3/content + ticket/1-3/links + ticket/1-3,5-7/history + + user/ams + user/ams/rights + user/ams,rai,1/rights + + For more information: + + - rt help <action> (action-specific details) + - rt help <type> (type-specific details) + +-- + +Title: actions +Title: commands +Text: + + You can currently perform the following actions on all objects: + + - list (list objects matching some condition) + - show (display object details) + - edit (edit object details) + - create (create a new object) + + Each type may define actions specific to itself; these are listed in + the help item about that type. + + For more information: + + - rt help <action> (action-specific details) + - rt help types (a list of possible types) + +-- + +Title: types +Text: + + You can currently operate on the following types of objects: + + - tickets + - users + - groups + - queues + + For more information: + + - rt help <type> (type-specific details) + - rt help objects (how to specify objects) + - rt help actions (a list of possible actions) + +-- + +Title: ticket +Text: + + Tickets are identified by a numeric ID. + + The following generic operations may be performed upon tickets: + + - list + - show + - edit + - create + + In addition, the following ticket-specific actions exist: + + - link + - merge + - comment + - correspond + + Attributes: + + The following attributes can be used with "rt show" or "rt edit" + to retrieve or edit other information associated with tickets: + + links A ticket's relationships with others. + history All of a ticket's transactions. + history/type/<type> Only a particular type of transaction. + history/id/<id> Only the transaction of the specified id. + attachments A list of attachments. + attachments/<id> The metadata for an individual attachment. + attachments/<id>/content The content of an individual attachment. + +-- + +Title: user +Title: group +Text: + + Users and groups are identified by name or numeric ID. + + The following generic operations may be performed upon them: + + - list + - show + - edit + - create + + In addition, the following type-specific actions exist: + + - grant + - revoke + + Attributes: + + The following attributes can be used with "rt show" or "rt edit" + to retrieve or edit other information associated with users and + groups: + + rights Global rights granted to this user. + rights/<queue> Queue rights for this user. + +-- + +Title: queue +Text: + + Queues are identified by name or numeric ID. + + Currently, they can be subjected to the following actions: + + - show + - edit + - create + +-- + +Title: logout +Text: + + Syntax: + + rt logout + + Terminates the currently established login session. You will need to + provide authentication credentials before you can continue using the + server. (See "rt help config" for details about authentication.) + +-- + +Title: ls +Title: list +Title: search +Text: + + Syntax: + + rt <ls|list|search> [options] "query string" + + Displays a list of objects matching the specified conditions. + ("ls", "list", and "search" are synonyms.) + + Conditions are expressed in the SQL-like syntax used internally by + RT3. (For more information, see "rt help query".) The query string + must be supplied as one argument. + + (Right now, the server doesn't support listing anything but tickets. + Other types will be supported in future; this client will be able to + take advantage of that support without any changes.) + + Options: + + The following options control how much information is displayed + about each matching object: + + -i Numeric IDs only. (Useful for |rt edit -; see examples.) + -s Short description. + -l Longer description. + + In addition, + + -o +/-<field> Orders the returned list by the specified field. + -S var=val Submits the specified variable with the request. + -t type Specifies the type of object to look for. (The + default is "ticket".) + + Examples: + + rt ls "Priority > 5 and Status='new'" + rt ls -o +Subject "Priority > 5 and Status='new'" + rt ls -o -Created "Priority > 5 and Status='new'" + rt ls -i "Priority > 5"|rt edit - set status=resolved + rt ls -t ticket "Subject like '[PATCH]%'" + +-- + +Title: show +Text: + + Syntax: + + rt show [options] <object-ids> + + Displays details of the specified objects. + + For some types, object information is further classified into named + attributes (for example, "1-3/links" is a valid ticket specification + that refers to the links for tickets 1-3). Consult "rt help <type>" + and "rt help objects" for further details. + + This command writes a set of forms representing the requested object + data to STDOUT. + + Options: + + - Read IDs from STDIN instead of the command-line. + -t type Specifies object type. + -f a,b,c Restrict the display to the specified fields. + -S var=val Submits the specified variable with the request. + + Examples: + + rt show -t ticket -f id,subject,status 1-3 + rt show ticket/3/attachments/29 + rt show ticket/3/attachments/29/content + rt show ticket/1-3/links + rt show -t user 2 + +-- + +Title: new +Title: edit +Title: create +Text: + + Syntax: + + rt edit [options] <object-ids> set field=value [field=value] ... + add field=value [field=value] ... + del field=value [field=value] ... + + Edits information corresponding to the specified objects. + + If, instead of "edit", an action of "new" or "create" is specified, + then a new object is created. In this case, no numeric object IDs + may be specified, but the syntax and behaviour remain otherwise + unchanged. + + This command typically starts an editor to allow you to edit object + data in a form for submission. If you specified enough information + on the command-line, however, it will make the submission directly. + + The command line may specify field-values in three different ways. + "set" sets the named field to the given value, "add" adds a value + to a multi-valued field, and "del" deletes the corresponding value. + Each "field=value" specification must be given as a single argument. + + For some types, object information is further classified into named + attributes (for example, "1-3/links" is a valid ticket specification + that refers to the links for tickets 1-3). These attributes may also + be edited. Consult "rt help <type>" and "rt help object" for further + details. + + Options: + + - Read numeric IDs from STDIN instead of the command-line. + (Useful with rt ls ... | rt edit -; see examples below.) + -i Read a completed form from STDIN before submitting. + -o Dump the completed form to STDOUT instead of submitting. + -e Allows you to edit the form even if the command-line has + enough information to make a submission directly. + -S var=val + Submits the specified variable with the request. + -t type Specifies object type. + + Examples: + + # Interactive (starts $EDITOR with a form). + rt edit ticket/3 + rt create -t ticket + + # Non-interactive. + rt edit ticket/1-3 add cc=foo@example.com set priority=3 + rt ls -t tickets -i 'Priority > 5' | rt edit - set status=resolved + rt edit ticket/4 set priority=3 owner=bar@example.com \ + add cc=foo@example.com bcc=quux@example.net + rt create -t ticket subject='new ticket' priority=10 \ + add cc=foo@example.com + +-- + +Title: comment +Title: correspond +Text: + + Syntax: + + rt <comment|correspond> [options] <ticket-id> + + Adds a comment (or correspondence) to the specified ticket (the only + difference being that comments aren't sent to the requestors.) + + This command will typically start an editor and allow you to type a + comment into a form. If, however, you specified all the necessary + information on the command line, it submits the comment directly. + + (See "rt help forms" for more information about forms.) + + Options: + + -m <text> Specify comment text. + -a <file> Attach a file to the comment. (May be used more + than once to attach multiple files.) + -c <addrs> A comma-separated list of Cc addresses. + -b <addrs> A comma-separated list of Bcc addresses. + -w <time> Specify the time spent working on this ticket. + -e Starts an editor before the submission, even if + arguments from the command line were sufficient. + + Examples: + + rt comment -t 'Not worth fixing.' -a stddisclaimer.h 23 + +-- + +Title: merge +Text: + + Syntax: + + rt merge <from-id> <to-id> + + Merges the two specified tickets. + +-- + +Title: link +Text: + + Syntax: + + rt link [-d] <id-A> <relationship> <id-B> + + Creates (or, with -d, deletes) a link between the specified tickets. + The relationship can (irrespective of case) be any of: + + DependsOn/DependedOnBy: A depends upon B (or vice versa). + RefersTo/ReferredToBy: A refers to B (or vice versa). + MemberOf/HasMember: A is a member of B (or vice versa). + + To view a ticket's relationships, use "rt show ticket/3/links". (See + "rt help ticket" and "rt help show".) + + Options: + + -d Deletes the specified link. + + Examples: + + rt link 2 dependson 3 + rt link -d 4 referredtoby 6 # 6 no longer refers to 4 + +-- + +Title: grant +Title: revoke +Text: + +-- + +Title: query +Text: + + RT3 uses an SQL-like syntax to specify object selection constraints. + See the <RT:...> documentation for details. + + (XXX: I'm going to have to write it, aren't I?) + +-- + +Title: form +Title: forms +Text: + + This program uses RFC822 header-style forms to represent object data + in a form that's suitable for processing both by humans and scripts. + + A form is a set of (field, value) specifications, with some initial + commented text and interspersed blank lines allowed for convenience. + Field names may appear more than once in a form; a comma-separated + list of multiple field values may also be specified directly. + + Field values can be wrapped as in RFC822, with leading whitespace. + The longest sequence of leading whitespace common to all the lines + is removed (preserving further indentation). There is no limit on + the length of a value. + + Multiple forms are separated by a line containing only "--\n". + + (XXX: A more detailed specification will be provided soon. For now, + the server-side syntax checking will suffice.) + +-- + +Title: topics +Text: + + Use "rt help <topic>" for help on any of the following subjects: + + - tickets, users, groups, queues. + - show, edit, ls/list/search, new/create. + + - query (search query syntax) + - forms (form specification) + + - objects (how to specify objects) + - types (a list of object types) + - actions/commands (a list of actions) + - usage/syntax (syntax details) + - conf/config/configuration (configuration details) + - examples (a few useful examples) + +-- + +Title: example +Title: examples +Text: + + This section will be filled in with useful examples, once it becomes + more clear what examples may be useful. + + For the moment, please consult examples provided with each action. + +-- diff --git a/rt/bin/webmux.pl b/rt/bin/webmux.pl index 21cb83f5e..96e7ebf8d 100755 --- a/rt/bin/webmux.pl +++ b/rt/bin/webmux.pl @@ -31,6 +31,7 @@ BEGIN { $ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'}; $ENV{'ENV'} = '' if defined $ENV{'ENV'}; $ENV{'IFS'} = '' if defined $ENV{'IFS'}; + } use lib ("/opt/rt3/local/lib", "/opt/rt3/lib"); @@ -42,6 +43,17 @@ use CGI qw(-private_tempfiles); #bring this in before mason, to make sure we #set private_tempfiles BEGIN { + if ($mod_perl::VERSION >= 1.9908) { + require Apache::RequestUtil; + no warnings 'redefine'; + my $sub = *Apache::request{CODE}; + *Apache::request = sub { + my $r; + eval { $r = $sub->('Apache'); }; + # warn $@ if $@; + return $r; + }; + } if ($CGI::MOD_PERL) { require HTML::Mason::ApacheHandler; } @@ -104,21 +116,32 @@ if ( $CGI::MOD_PERL) { unless ( ( -d _ ) and ( -r _ ) and ( -w _ ) ); } -my $ah = &RT::Interface::Web::NewApacheHandler() if $CGI::MOD_PERL; +my $ah = &RT::Interface::Web::NewApacheHandler(@RT::MasonParameters) if $CGI::MOD_PERL; sub handler { ($r) = @_; + local $SIG{__WARN__}; + local $SIG{__DIE__}; + RT::Init(); # We don't need to handle non-text items return -1 if defined( $r->content_type ) && $r->content_type !~ m|^text/|io; my %session; - my $status = $ah->handle_request($r); + my $status; + eval { $status = $ah->handle_request($r) }; + if ($@) { + $RT::Logger->crit($@); + } + undef (%session); - $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") if $RT::Handle->TransactionDepth; + if ($RT::Handle->TransactionDepth) { + $RT::Handle->ForceRollback; + $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") ; + } return $status; } diff --git a/rt/bin/webmux.pl.in b/rt/bin/webmux.pl.in index 12aad85b3..dca5705e9 100644 --- a/rt/bin/webmux.pl.in +++ b/rt/bin/webmux.pl.in @@ -31,6 +31,7 @@ BEGIN { $ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'}; $ENV{'ENV'} = '' if defined $ENV{'ENV'}; $ENV{'IFS'} = '' if defined $ENV{'IFS'}; + @ORACLE_ENV_PREF@ } use lib ("@LOCAL_LIB_PATH@", "@RT_LIB_PATH@"); @@ -42,6 +43,17 @@ use CGI qw(-private_tempfiles); #bring this in before mason, to make sure we #set private_tempfiles BEGIN { + if ($mod_perl::VERSION >= 1.9908) { + require Apache::RequestUtil; + no warnings 'redefine'; + my $sub = *Apache::request{CODE}; + *Apache::request = sub { + my $r; + eval { $r = $sub->('Apache'); }; + # warn $@ if $@; + return $r; + }; + } if ($CGI::MOD_PERL) { require HTML::Mason::ApacheHandler; } @@ -104,21 +116,32 @@ if ( $CGI::MOD_PERL) { unless ( ( -d _ ) and ( -r _ ) and ( -w _ ) ); } -my $ah = &RT::Interface::Web::NewApacheHandler() if $CGI::MOD_PERL; +my $ah = &RT::Interface::Web::NewApacheHandler(@RT::MasonParameters) if $CGI::MOD_PERL; sub handler { ($r) = @_; + local $SIG{__WARN__}; + local $SIG{__DIE__}; + RT::Init(); # We don't need to handle non-text items return -1 if defined( $r->content_type ) && $r->content_type !~ m|^text/|io; my %session; - my $status = $ah->handle_request($r); + my $status; + eval { $status = $ah->handle_request($r) }; + if ($@) { + $RT::Logger->crit($@); + } + undef (%session); - $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") if $RT::Handle->TransactionDepth; + if ($RT::Handle->TransactionDepth) { + $RT::Handle->ForceRollback; + $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") ; + } return $status; } diff --git a/rt/config.layout b/rt/config.layout index 81917f18c..23a7775d6 100644 --- a/rt/config.layout +++ b/rt/config.layout @@ -37,6 +37,27 @@ customlexdir: ${customdir}/po customlibdir: ${customdir}/lib </Layout> +<Layout inplace> + prefix: `pwd` + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + sysconfdir: ${prefix}/etc + mandir: ${prefix}/man + libdir: ${prefix}/lib + datadir: ${prefix}/share + htmldir: ${prefix}/html + manualdir: ${datadir}/doc + localstatedir: ${prefix}/var + logfiledir: ${localstatedir}/log + masonstatedir: ${localstatedir}/mason_data + sessionstatedir: ${localstatedir}/session_data + customdir: ${prefix}/local + custometcdir: ${customdir}/etc + customhtmldir: ${customdir}/html + customlexdir: ${customdir}/po + customlibdir: ${customdir}/lib +</Layout> <Layout FreeBSD> prefix: /usr/local diff --git a/rt/config.log b/rt/config.log index f8549485d..24e15e3cf 100644 --- a/rt/config.log +++ b/rt/config.log @@ -1,7 +1,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RT configure 3.0.4, which was +It was created by RT configure 3.0.9, which was generated by GNU Autoconf 2.53. Invocation command line was $ ./configure @@ -47,20 +47,20 @@ PATH: . ## Core tests. ## ## ----------- ## -configure:1217: checking for a BSD-compatible install -configure:1271: result: /usr/bin/install -c -configure:1285: checking for perl -configure:1303: found /usr/bin/perl -configure:1316: result: /usr/bin/perl -configure:1638: checking for chosen layout -configure:1653: result: RT3 -configure:1964: creating ./config.status +configure:1218: checking for a BSD-compatible install +configure:1272: result: /usr/bin/install -c +configure:1286: checking for perl +configure:1304: found /usr/bin/perl +configure:1317: result: /usr/bin/perl +configure:1639: checking for chosen layout +configure:1654: result: RT3 +configure:1986: creating ./config.status ## ---------------------- ## ## Running config.status. ## ## ---------------------- ## -This file was extended by RT config.status 3.0.4, which was +This file was extended by RT config.status 3.0.9, which was generated by GNU Autoconf 2.53. Invocation command line was CONFIG_FILES = @@ -71,23 +71,24 @@ generated by GNU Autoconf 2.53. Invocation command line was on pallas -config.status:637: creating sbin/rt-setup-database -config.status:637: creating sbin/rt-test-dependencies -config.status:637: creating Makefile -config.status:637: creating etc/RT_Config.pm -config.status:637: creating lib/RT.pm -config.status:637: creating lib/t/00smoke.t -config.status:637: creating lib/t/01harness.t -config.status:637: creating lib/t/02regression.t -config.status:637: creating lib/t/03web.pl -config.status:637: creating lib/t/04_send_email.pl -config.status:637: creating bin/mason_handler.fcgi -config.status:637: creating bin/mason_handler.scgi -config.status:637: creating bin/mason_handler.svc -config.status:637: creating bin/rt-commit-handler -config.status:637: creating bin/rt-crontool -config.status:637: creating bin/rt-mailgate -config.status:637: creating bin/webmux.pl +config.status:639: creating sbin/rt-setup-database +config.status:639: creating sbin/rt-test-dependencies +config.status:639: creating Makefile +config.status:639: creating etc/RT_Config.pm +config.status:639: creating lib/RT.pm +config.status:639: creating lib/t/00smoke.t +config.status:639: creating lib/t/01harness.t +config.status:639: creating lib/t/02regression.t +config.status:639: creating lib/t/03web.pl +config.status:639: creating lib/t/04_send_email.pl +config.status:639: creating bin/mason_handler.fcgi +config.status:639: creating bin/mason_handler.scgi +config.status:639: creating bin/mason_handler.svc +config.status:639: creating bin/rt-commit-handler +config.status:639: creating bin/rt-crontool +config.status:639: creating bin/rt-mailgate +config.status:639: creating bin/rt +config.status:639: creating bin/webmux.pl ## ---------------- ## ## Cache variables. ## @@ -110,8 +111,8 @@ ac_cv_path_install='/usr/bin/install -c' #define PACKAGE_NAME "RT" #define PACKAGE_TARNAME "rt" -#define PACKAGE_VERSION "3.0.4" -#define PACKAGE_STRING "RT 3.0.4" +#define PACKAGE_VERSION "3.0.9" +#define PACKAGE_STRING "RT 3.0.9" #define PACKAGE_BUGREPORT "rt-3.0-bugs@fsck.com" configure: exit 0 diff --git a/rt/config.status b/rt/config.status index e7d835894..e7d81b358 100755 --- a/rt/config.status +++ b/rt/config.status @@ -237,7 +237,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by RT $as_me 3.0.4, which was +This file was extended by RT $as_me 3.0.9, which was generated by GNU Autoconf 2.53. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -249,7 +249,7 @@ generated by GNU Autoconf 2.53. Invocation command line was _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 -config_files=" sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/webmux.pl" +config_files=" sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/rt bin/webmux.pl" ac_cs_usage="\ \`$as_me' instantiates files from templates according to the @@ -269,7 +269,7 @@ $config_files Report bugs to <bug-autoconf@gnu.org>." ac_cs_version="\ -RT config.status 3.0.4 +RT config.status 3.0.9 configured by ./configure, generated by GNU Autoconf 2.53, with options \"\" @@ -358,6 +358,7 @@ do "bin/rt-commit-handler" ) CONFIG_FILES="$CONFIG_FILES bin/rt-commit-handler" ;; "bin/rt-crontool" ) CONFIG_FILES="$CONFIG_FILES bin/rt-crontool" ;; "bin/rt-mailgate" ) CONFIG_FILES="$CONFIG_FILES bin/rt-mailgate" ;; + "bin/rt" ) CONFIG_FILES="$CONFIG_FILES bin/rt" ;; "bin/webmux.pl" ) CONFIG_FILES="$CONFIG_FILES bin/webmux.pl" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} @@ -410,8 +411,8 @@ s,@SHELL@,/bin/sh,;t t s,@PATH_SEPARATOR@,:,;t t s,@PACKAGE_NAME@,RT,;t t s,@PACKAGE_TARNAME@,rt,;t t -s,@PACKAGE_VERSION@,3.0.4,;t t -s,@PACKAGE_STRING@,RT 3.0.4,;t t +s,@PACKAGE_VERSION@,3.0.9,;t t +s,@PACKAGE_STRING@,RT 3.0.9,;t t s,@PACKAGE_BUGREPORT@,rt-3.0-bugs@fsck.com,;t t s,@exec_prefix@,/opt/rt3,;t t s,@prefix@,/opt/rt3,;t t @@ -431,14 +432,14 @@ s,@mandir@,/opt/rt3/man,;t t s,@build_alias@,,;t t s,@host_alias@,,;t t s,@target_alias@,,;t t -s,@DEFS@,-DPACKAGE_NAME=\"RT\" -DPACKAGE_TARNAME=\"rt\" -DPACKAGE_VERSION=\"3.0.4\" -DPACKAGE_STRING=\"RT\ 3.0.4\" -DPACKAGE_BUGREPORT=\"rt-3.0-bugs@fsck.com\" ,;t t +s,@DEFS@,-DPACKAGE_NAME=\"RT\" -DPACKAGE_TARNAME=\"rt\" -DPACKAGE_VERSION=\"3.0.9\" -DPACKAGE_STRING=\"RT\ 3.0.9\" -DPACKAGE_BUGREPORT=\"rt-3.0-bugs@fsck.com\" ,;t t s,@ECHO_C@,,;t t s,@ECHO_N@,-n,;t t s,@ECHO_T@,,;t t s,@LIBS@,,;t t s,@rt_version_major@,3,;t t s,@rt_version_minor@,0,;t t -s,@rt_version_patch@,4,;t t +s,@rt_version_patch@,9,;t t s,@INSTALL_PROGRAM@,${INSTALL},;t t s,@INSTALL_SCRIPT@,${INSTALL},;t t s,@INSTALL_DATA@,${INSTALL} -m 644,;t t @@ -479,6 +480,7 @@ s,@BIN_OWNER@,root,;t t s,@LIBS_OWNER@,root,;t t s,@LIBS_GROUP@,bin,;t t s,@DB_TYPE@,mysql,;t t +s,@ORACLE_ENV_PREF@,,;t t s,@DB_HOST@,localhost,;t t s,@DB_PORT@,,;t t s,@DB_RT_HOST@,localhost,;t t @@ -490,7 +492,7 @@ s,@WEB_USER@,www,;t t s,@WEB_GROUP@,www,;t t s,@RT_VERSION_MAJOR@,3,;t t s,@RT_VERSION_MINOR@,0,;t t -s,@RT_VERSION_PATCH@,4,;t t +s,@RT_VERSION_PATCH@,9,;t t s,@RT_PATH@,/opt/rt3,;t t s,@RT_DOC_PATH@,/opt/rt3/share/doc,;t t s,@RT_LOCAL_PATH@,/opt/rt3/local,;t t diff --git a/rt/configure b/rt/configure index c89d759fd..a90675888 100755 --- a/rt/configure +++ b/rt/configure @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision: 1.1 . # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.53 for RT 3.0.4. +# Generated by GNU Autoconf 2.53 for RT 3.0.9. # # Report bugs to <rt-3.0-bugs@fsck.com>. # @@ -257,8 +257,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='RT' PACKAGE_TARNAME='rt' -PACKAGE_VERSION='3.0.4' -PACKAGE_STRING='RT 3.0.4' +PACKAGE_VERSION='3.0.9' +PACKAGE_STRING='RT 3.0.9' PACKAGE_BUGREPORT='rt-3.0-bugs@fsck.com' ac_unique_file="lib/RT.pm.in" @@ -711,7 +711,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures RT 3.0.4 to adapt to many kinds of systems. +\`configure' configures RT 3.0.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -768,7 +768,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RT 3.0.4:";; + short | recursive ) echo "Configuration of RT 3.0.9:";; esac cat <<\_ACEOF @@ -786,8 +786,8 @@ Optional Packages: --with-bin-owner=OWNER user that will own rt binaries (default root) --with-libs-owner=OWNER user that will own RT libraries (default root) --with-libs-group=GROUP group that will own rt binaries (default bin) - --with-db-type=TYPE sort of database RT will use (default: mysql) (mysql - and Pg are valid) + --with-db-type=TYPE sort of database RT will use (default: mysql) + (mysql, Pg, Oracle and Informix are valid) --with-db-host=HOSTNAME FQDN of database server (default: localhost) --with-db-port=PORT port on which the database listens on --with-db-rt-host=HOSTNAME @@ -802,6 +802,7 @@ Optional Packages: password for database user (default: rt_pass) --with-web-user=USER user the web server runs as (default: www) --with-web-group=GROUP group the web server runs as (default: www) + --with-my-user-group set all users and groups to current user/group Some influential environment variables: PERL Perl interpreter command @@ -872,7 +873,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -RT configure 3.0.4 +RT configure 3.0.9 generated by GNU Autoconf 2.53 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 @@ -887,7 +888,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RT $as_me 3.0.4, which was +It was created by RT $as_me 3.0.9, which was generated by GNU Autoconf 2.53. Invocation command line was $ $0 $@ @@ -1171,7 +1172,7 @@ rt_version_major=3 rt_version_minor=0 -rt_version_patch=4 +rt_version_patch=9 test "x$rt_version_major" = 'x' && rt_version_major=0 test "x$rt_version_minor" = 'x' && rt_version_minor=0 @@ -1703,13 +1704,21 @@ if test "${with_db_type+set}" = set; then else DB_TYPE=mysql fi; -if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite'; then - { { echo "$as_me:$LINENO: error: Only Pg and mysql are valid db types" >&5 -echo "$as_me: error: Only Pg and mysql are valid db types" >&2;} +if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite' -a "$DB_TYPE" != 'Oracle' -a "$DB_TYPE" != 'Informix' ; then + { { echo "$as_me:$LINENO: error: Only Oracle, Informix, Pg and mysql are valid db types" >&5 +echo "$as_me: error: Only Oracle, Informix, Pg and mysql are valid db types" >&2;} { (exit 1); exit 1; }; } fi +if test "$DB_TYPE" = 'Oracle'; then + test "x$ORACLE_HOME" = 'x' && { { echo "$as_me:$LINENO: error: Please declare the ORACLE_HOME environment variable" >&5 +echo "$as_me: error: Please declare the ORACLE_HOME environment variable" >&2;} + { (exit 1); exit 1; }; } + ORACLE_ENV_PREF="\$ENV{'ORACLE_HOME'} = '$ORACLE_HOME';" +fi + + # Check whether --with-db-host or --without-db-host was given. if test "${with_db_host+set}" = set; then @@ -1800,6 +1809,19 @@ else fi; +my_group=$(groups|cut -f1 -d' ') + +# Check whether --with-my-user-group or --without-my-user-group was given. +if test "${with_my_user_group+set}" = set; then + withval="$with_my_user_group" + RTGROUP=$my_group + BIN_OWNER=$USER + LIBS_OWNER=$USER + LIBS_GROUP=$my_group + WEB_USER=$USER + WEB_GROUP=$my_group +fi; + RT_VERSION_MAJOR=${rt_version_major} @@ -1848,7 +1870,7 @@ RT_LOG_PATH=${exp_logfiledir} -ac_config_files="$ac_config_files sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/webmux.pl" +ac_config_files="$ac_config_files sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/rt bin/webmux.pl" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -2206,7 +2228,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by RT $as_me 3.0.4, which was +This file was extended by RT $as_me 3.0.9, which was generated by GNU Autoconf 2.53. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -2260,7 +2282,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -RT config.status 3.0.4 +RT config.status 3.0.9 configured by $0, generated by GNU Autoconf 2.53, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -2363,6 +2385,7 @@ do "bin/rt-commit-handler" ) CONFIG_FILES="$CONFIG_FILES bin/rt-commit-handler" ;; "bin/rt-crontool" ) CONFIG_FILES="$CONFIG_FILES bin/rt-crontool" ;; "bin/rt-mailgate" ) CONFIG_FILES="$CONFIG_FILES bin/rt-mailgate" ;; + "bin/rt" ) CONFIG_FILES="$CONFIG_FILES bin/rt" ;; "bin/webmux.pl" ) CONFIG_FILES="$CONFIG_FILES bin/webmux.pl" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} @@ -2487,6 +2510,7 @@ s,@BIN_OWNER@,$BIN_OWNER,;t t s,@LIBS_OWNER@,$LIBS_OWNER,;t t s,@LIBS_GROUP@,$LIBS_GROUP,;t t s,@DB_TYPE@,$DB_TYPE,;t t +s,@ORACLE_ENV_PREF@,$ORACLE_ENV_PREF,;t t s,@DB_HOST@,$DB_HOST,;t t s,@DB_PORT@,$DB_PORT,;t t s,@DB_RT_HOST@,$DB_RT_HOST,;t t diff --git a/rt/configure.ac b/rt/configure.ac index cd82c4460..ea5de5e15 100644 --- a/rt/configure.ac +++ b/rt/configure.ac @@ -2,11 +2,11 @@ dnl dnl Process this file with autoconf to produce a configure script dnl dnl Embed in generated ./configure script the following CVS info: -AC_REVISION($Revision: 1.1 $)dnl +AC_REVISION($Revision: 1.1.1.2 $)dnl dnl Setup autoconf AC_PREREQ(2.53) -AC_INIT(RT, [3.0.4], [rt-3.0-bugs@fsck.com]) +AC_INIT(RT, [3.0.9], [rt-3.0-bugs@fsck.com]) AC_CONFIG_SRCDIR([lib/RT.pm.in]) dnl Extract RT version number components @@ -75,14 +75,21 @@ AC_SUBST(LIBS_GROUP) dnl DB_TYPE AC_ARG_WITH(db-type, AC_HELP_STRING([--with-db-type=TYPE], - [sort of database RT will use (default: mysql) (mysql and Pg are valid)]), + [sort of database RT will use (default: mysql) (mysql, Pg, Oracle and Informix are valid)]), DB_TYPE=$withval, DB_TYPE=mysql) -if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite'; then - AC_MSG_ERROR([Only Pg and mysql are valid db types]) +if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite' -a "$DB_TYPE" != 'Oracle' -a "$DB_TYPE" != 'Informix' ; then + AC_MSG_ERROR([Only Oracle, Informix, Pg and mysql are valid db types]) fi AC_SUBST(DB_TYPE) +dnl ORACLE_ENV_PREF +if test "$DB_TYPE" = 'Oracle'; then + test "x$ORACLE_HOME" = 'x' && AC_MSG_ERROR([Please declare the ORACLE_HOME environment variable]) + ORACLE_ENV_PREF="\$ENV{'ORACLE_HOME'} = '$ORACLE_HOME';" +fi +AC_SUBST(ORACLE_ENV_PREF) + dnl DB_HOST AC_ARG_WITH(db-host, AC_HELP_STRING([--with-db-host=HOSTNAME], @@ -155,6 +162,18 @@ AC_ARG_WITH(web-group, WEB_GROUP=www) AC_SUBST(WEB_GROUP) +dnl INSTALL AS ME +my_group=$(groups|cut -f1 -d' ') +AC_ARG_WITH(my-user-group, + AC_HELP_STRING([--with-my-user-group], + [set all users and groups to current user/group]), + RTGROUP=$my_group + BIN_OWNER=$USER + LIBS_OWNER=$USER + LIBS_GROUP=$my_group + WEB_USER=$USER + WEB_GROUP=$my_group) + dnl This section maps the variable names this script 'natively' generates dnl to their existing names. They should be removed from here as the .in dnl files are changed to use the new names. @@ -204,6 +223,7 @@ AC_CONFIG_FILES([ bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate + bin/rt bin/webmux.pl] ) AC_OUTPUT diff --git a/rt/docs/rt3-schema-relationships.dot b/rt/docs/rt3-schema-relationships.dot new file mode 100644 index 000000000..77ed35f01 --- /dev/null +++ b/rt/docs/rt3-schema-relationships.dot @@ -0,0 +1,81 @@ +digraph g { +graph [ +rankdir = "LR", +concentrate = true, +ratio = auto +]; +node [ +fontsize = "18", +shape = record, fontsize = 18 +]; +edge [ +]; + +"ACL" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"ACL" -> "Principals" [label="PrincipalId -> Id"]; +"ACL" -> "Principals" [label="DelegatedBy -> Id"]; +"ACL" -> "ACL" [label="DelegatedFrom -> Id"]; + +"Attachments" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"Attachments" -> "Transactions" [label="TransactionId -> id"]; +"Attachments" -> "Attachments" [label="Parent -> id"]; + +"CachedGroupMemers" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"CachedGroupMemers" -> "Groups" [label="GroupId -> Groups.id"]; +"CachedGroupMemers" -> "Principals" [label="MemberId -> Id"]; +"CachedGroupMemers" -> "CachedGroupMemers" [label="Via -> id"]; +"CachedGroupMemers" -> "Groups" [label="ImmediateParentId -> Groups.id"]; + +"CustomFields" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"CustomFields" -> "Queues" [label="Queue -> id"]; + +"CustomFieldValues" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"CustomFieldValues" -> "CustomFields" [label="CustomField -> id"]; + +"GroupMembers" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"GroupMembers" -> "Groups" [label="GroupId => Groups.Id"]; +"GroupMembers" -> "Principals" [label="MemberId => Id"]; + +"Groups" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"Groups" -> "Principals" [label="Groups.id -> id"]; + +"Links" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"Links" -> "Tickets" [label="LocalBase => id (usually)"]; +"Links" -> "Tickets" [label="LocalTarget => id (usually)"]; + +"Principals" [shape = record, fontsize = 18, label = "<col0> \N " ]; + + +"Queues" [shape = record, fontsize = 18, label = "<col0> \N " ]; + +"ScripActions" [shape = record, fontsize = 18, label = "<col0> \N " ]; + +"ScripConditions" [shape = record, fontsize = 18, label = "<col0> \N " ]; + +"Scrips" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"Scrips" -> "ScripConditions" [label="ScripCondition -> id"]; +"Scrips" -> "ScripActions" [label="ScripAction -> id"]; +"Scrips" -> "Templates" [label="Template -> id"]; +"Scrips" -> "Queues" [label="Queue -> id"]; + +"Templates" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"Templates" -> "Queues" [label ="Queue -> id" ]; + +"TicketCustomFieldValues" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"TicketCustomFieldValues" -> "Tickets" [label="Ticket -> id"]; +"TicketCustomFieldValues" -> "CustomFields" [label="CustomField -> id"]; + +"Tickets" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"Tickets" -> "Tickets" [label="EffectiveId -> id"]; +"Tickets" -> "Queues" [label="Queue -> id"]; +"Tickets" -> "Principals" [label="Owner -> id"]; + +"Transactions" [shape = record, fontsize = 18, label = "<col0> \N " ]; +"Transactions" -> "Tickets" [label="Ticket -> Id"]; + +"Users" [shape = record, fontsize = 18, label = "<col0> \N " ]; + +"Users" -> "Principals" [label="id -> id"]; + + +} diff --git a/rt/etc/RT_Config.pm b/rt/etc/RT_Config.pm index 2b3f4f9fe..5386a8e05 100644 --- a/rt/etc/RT_Config.pm +++ b/rt/etc/RT_Config.pm @@ -47,7 +47,7 @@ Set($Timezone , 'US/Eastern'); # {{{ Database Configuration # Database driver beeing used. Case matters -# Valid types are "mysql" and "Pg" +# Valid types are "mysql", "Oracle" and "Pg" Set($DatabaseType , 'mysql'); @@ -164,9 +164,9 @@ Set($SenderMustExistInExternalDatabase , undef); # and comment mail tracked by RT, unless overridden by a queue-specific # address. -Set($CorrespondAddress , 'RT::CorrespondAddress.not.set'); +Set($CorrespondAddress , 'RT_CorrespondAddressNotSet'); -Set($CommentAddress , 'RT::CommentAddress.not.set'); +Set($CommentAddress , 'RT_CommentAddressNotSet'); #Sendmail Configuration @@ -268,9 +268,6 @@ Set($WebBaseURL , "http://RT::WebBaseURL.not.configured:80"); Set($WebURL , $WebBaseURL . $WebPath . "/"); # $WebImagesURL points to the base URL where RT can find its images. -# If you're running the FastCGI version of the RT web interface, -# you should make RT's WebRT/html/NoAuth/images directory available on -# a static web server and supply that URL as $WebImagesURL. Set($WebImagesURL , $WebURL . "NoAuth/images/"); @@ -278,6 +275,15 @@ Set($WebImagesURL , $WebURL . "NoAuth/images/"); Set($LogoURL , $WebImagesURL . "rt.jpg"); +# For message boxes, set the entry box width and what type of wrapping +# to use. +# +# Default width: 72 +Set($MessageBoxWidth , 72); + +# Default wrapping: "HARD" (choices "SOFT", "HARD") +Set($MessageBoxWrap, "HARD"); + # if TrustHTMLAttachments is not defined, we will display them # as text. This prevents malicious HTML and javascript from being # sent in a request (although there is probably more to it than that) @@ -310,6 +316,25 @@ Set($WebExternalAuto , undef); # Set($WebSessionClass , 'Apache::Session::File'); +# $MaxInlineBody is the maximum attachment size that we want to see +# inline when viewing a transaction. 13456 is a random sane-sounding +# default. + +Set($MaxInlineBody, 13456); + +# $MyTicketsLength is the length of the table on the front page. +# For some people, the default of 10 isn't big enough to get a feel for +# how much work needs to be done before you get some time off. + +Set($MyTicketsLength, 10); + +# @MasonParameters is the list of parameters for the constructor of +# HTML::Mason's Apache or CGI Handler. This is normally only useful +# for debugging, eg. profiling individual components with +# (preamble => 'my $p = MasonX::Profiler->new($m, $r);'); + +@MasonParameters = () unless (@MasonParameters); + # }}} # {{{ RT UTF-8 Settings diff --git a/rt/etc/RT_Config.pm.in b/rt/etc/RT_Config.pm.in index 5f97eb0a0..8271a7760 100644 --- a/rt/etc/RT_Config.pm.in +++ b/rt/etc/RT_Config.pm.in @@ -47,7 +47,7 @@ Set($Timezone , 'US/Eastern'); # {{{ Database Configuration # Database driver beeing used. Case matters -# Valid types are "mysql" and "Pg" +# Valid types are "mysql", "Oracle" and "Pg" Set($DatabaseType , '@DB_TYPE@'); @@ -164,9 +164,9 @@ Set($SenderMustExistInExternalDatabase , undef); # and comment mail tracked by RT, unless overridden by a queue-specific # address. -Set($CorrespondAddress , 'RT::CorrespondAddress.not.set'); +Set($CorrespondAddress , 'RT_CorrespondAddressNotSet'); -Set($CommentAddress , 'RT::CommentAddress.not.set'); +Set($CommentAddress , 'RT_CommentAddressNotSet'); #Sendmail Configuration @@ -268,9 +268,6 @@ Set($WebBaseURL , "http://RT::WebBaseURL.not.configured:80"); Set($WebURL , $WebBaseURL . $WebPath . "/"); # $WebImagesURL points to the base URL where RT can find its images. -# If you're running the FastCGI version of the RT web interface, -# you should make RT's WebRT/html/NoAuth/images directory available on -# a static web server and supply that URL as $WebImagesURL. Set($WebImagesURL , $WebURL . "NoAuth/images/"); @@ -278,6 +275,15 @@ Set($WebImagesURL , $WebURL . "NoAuth/images/"); Set($LogoURL , $WebImagesURL . "rt.jpg"); +# For message boxes, set the entry box width and what type of wrapping +# to use. +# +# Default width: 72 +Set($MessageBoxWidth , 72); + +# Default wrapping: "HARD" (choices "SOFT", "HARD") +Set($MessageBoxWrap, "HARD"); + # if TrustHTMLAttachments is not defined, we will display them # as text. This prevents malicious HTML and javascript from being # sent in a request (although there is probably more to it than that) @@ -310,6 +316,25 @@ Set($WebExternalAuto , undef); # Set($WebSessionClass , 'Apache::Session::File'); +# $MaxInlineBody is the maximum attachment size that we want to see +# inline when viewing a transaction. 13456 is a random sane-sounding +# default. + +Set($MaxInlineBody, 13456); + +# $MyTicketsLength is the length of the table on the front page. +# For some people, the default of 10 isn't big enough to get a feel for +# how much work needs to be done before you get some time off. + +Set($MyTicketsLength, 10); + +# @MasonParameters is the list of parameters for the constructor of +# HTML::Mason's Apache or CGI Handler. This is normally only useful +# for debugging, eg. profiling individual components with +# (preamble => 'my $p = MasonX::Profiler->new($m, $r);'); + +@MasonParameters = () unless (@MasonParameters); + # }}} # {{{ RT UTF-8 Settings diff --git a/rt/etc/acl.Informix b/rt/etc/acl.Informix new file mode 100644 index 000000000..bca0408dd --- /dev/null +++ b/rt/etc/acl.Informix @@ -0,0 +1,5 @@ +sub acl { +return ( +"GRANT RESOURCE TO ${RT::DatabaseUser};"); +} +1; diff --git a/rt/etc/acl.Oracle b/rt/etc/acl.Oracle index c8667c031..ac29215c2 100644 --- a/rt/etc/acl.Oracle +++ b/rt/etc/acl.Oracle @@ -1,10 +1,10 @@ sub acl { return ( -"CREATE USER ${RT::DatabaseUser} identified by ${RT::DatabasePassword}". -"temporary tablespace TEMP" . -"default tablespace USERS" . -"quota unlimited on USERS;" , -"grant connect, resource to ${RT::DatabaseUser};", -"exit;"); +"CREATE USER ${RT::DatabaseUser} identified by ${RT::DatabasePassword} ". +"default tablespace USERS " . +"temporary tablespace TEMP " . +"quota unlimited on USERS" , +"grant connect, resource to ${RT::DatabaseUser}" +); } 1; diff --git a/rt/etc/constraints.mysql b/rt/etc/constraints.mysql index 33a037673..fd557d5e4 100644 --- a/rt/etc/constraints.mysql +++ b/rt/etc/constraints.mysql @@ -1,8 +1,5 @@ -#ALTER TABLE Users ADD FOREIGN KEY (Creator) REFERENCES Users(id); -#ALTER TABLE Users ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id); ALTER TABLE Links ADD FOREIGN KEY (LocalBase) REFERENCES Tickets(id) ; ALTER TABLE Links ADD FOREIGN KEY (LocalTarget) REFERENCES Tickets(id); - ObjectId integer, # FOREIGN KEY to Users or Groups, depending ALTER TABLE Tickets ADD FOREIGN KEY (Queue) REFERENCES Queues(id); ALTER TABLE Tickets ADD FOREIGN KEY (EffectiveId) REFERENCES Tickets(id); ALTER TABLE Tickets ADD FOREIGN KEY (Owner) REFERENCES Principals(id); @@ -19,18 +16,11 @@ ALTER TABLE Scrips ADD FOREIGN KEY (Queue) REFERENCES Queues(id); ALTER TABLE Scrips ADD FOREIGN KEY (Creator) REFERENCES Users(id); ALTER TABLE Scrips ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id); - PrincipalId integer NOT NULL , #ALTER TABLE ADD FOREIGN KEY to principals - DelegatedBy integer NOT NULL default 0, #ALTER TABLE ADD FOREIGN KEY to principals with a userid - DelegatedFrom integer NOT NULL default 0, #ALTER TABLE ADD FOREIGN KEY to ACL ALTER TABLE ACL ADD FOREIGN KEY (PrincipalId) REFERENCES Principals(id); ALTER TABLE ACL ADD FOREIGN KEY (DelegatedBy) REFERENCES Principals(id); ALTER TABLE ACL ADD FOREIGN KEY (DelegatedFrom) REFERENCES ACL(id); - ALTER TABLE GroupMembers ADD FOREIGN KEY (GroupId) REFERENCES Principals(id); + ALTER TABLE GroupMembers ADD FOREIGN KEY (GroupId) REFERENCES Groups(id); ALTER TABLE GroupMembers ADD FOREIGN KEY (MemberId) REFERENCES Principals(id); - GroupId int, # ALTER TABLE ADD FOREIGN KEY to Principals - MemberId int, # ALTER TABLE ADD FOREIGN KEY to Principals - Via int, #ALTER TABLE ADD FOREIGN KEY to CachedGroupMembers. (may point to $self->id) - ImmediateParentId int, #ALTER TABLE ADD FOREIGN KEY to prinicpals. ALTER TABLE CachedGroupMembers ADD FOREIGN KEY (ImmediateParentId) REFERENCES Principals(id); ALTER TABLE CachedGroupMembers ADD FOREIGN KEY (GroupId) REFERENCES Principals(id); ALTER TABLE CachedGroupMembers ADD FOREIGN KEY (MemberId) REFERENCES Principals(id); @@ -43,7 +33,7 @@ ALTER TABLE CustomFields ADD FOREIGN KEY (Queue) REFERENCES Queues(id); ALTER TABLE CustomFields ADD FOREIGN KEY (Creator) REFERENCES Users(id); ALTER TABLE CustomFields ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id); - ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (Ticket) REFERENCES Ticketss(id); + ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (Ticket) REFERENCES Tickets(id); ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (CustomField) REFERENCES CustomFields(id); ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (Creator) REFERENCES Users(id); ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id); diff --git a/rt/etc/drop.Informix b/rt/etc/drop.Informix new file mode 100644 index 000000000..ce7cc0181 --- /dev/null +++ b/rt/etc/drop.Informix @@ -0,0 +1,19 @@ +DROP TABLE ACL; +DROP TABLE ATTACHMENTS; +DROP TABLE CACHEDGROUPMEMBERS; +DROP TABLE CUSTOMFIELDS; +DROP TABLE CUSTOMFIELDVALUES; +DROP TABLE GROUPMEMBERS; +DROP TABLE GROUPS; +DROP TABLE LINKS; +DROP TABLE PRINCIPALS; +DROP TABLE QUEUES; +DROP TABLE SCRIPACTIONS; +DROP TABLE SCRIPCONDITIONS; +DROP TABLE SCRIPS; +DROP TABLE SESSIONS; +DROP TABLE TEMPLATES; +DROP TABLE TICKETCUSTOMFIELDVALUES; +DROP TABLE TICKETS; +DROP TABLE TRANSACTIONS; +DROP TABLE USERS; diff --git a/rt/etc/drop.Oracle b/rt/etc/drop.Oracle new file mode 100644 index 000000000..dd11376f2 --- /dev/null +++ b/rt/etc/drop.Oracle @@ -0,0 +1,37 @@ +DROP TABLE ACL; +DROP TABLE ATTACHMENTS; +DROP TABLE CACHEDGROUPMEMBERS; +DROP TABLE CUSTOMFIELDS; +DROP TABLE CUSTOMFIELDVALUES; +DROP TABLE GROUPMEMBERS; +DROP TABLE GROUPS; +DROP TABLE LINKS; +DROP TABLE PRINCIPALS; +DROP TABLE QUEUES; +DROP TABLE SCRIPACTIONS; +DROP TABLE SCRIPCONDITIONS; +DROP TABLE SCRIPS; +DROP TABLE SESSIONS; +DROP TABLE TEMPLATES; +DROP TABLE TICKETCUSTOMFIELDVALUES; +DROP TABLE TICKETS; +DROP TABLE TRANSACTIONS; +DROP TABLE USERS; +DROP SEQUENCE ACL_seq; +DROP SEQUENCE ATTACHMENTS_seq; +DROP SEQUENCE CACHEDGROUPMEMBERS_seq; +DROP SEQUENCE CUSTOMFIELDS_seq; +DROP SEQUENCE CUSTOMFIELDVALUES_seq; +DROP SEQUENCE GROUPMEMBERS_seq; +DROP SEQUENCE GROUPS_seq; +DROP SEQUENCE LINKS_seq; +DROP SEQUENCE PRINCIPALS_seq; +DROP SEQUENCE QUEUES_seq; +DROP SEQUENCE SCRIPACTIONS_seq; +DROP SEQUENCE SCRIPCONDITIONS_seq; +DROP SEQUENCE SCRIPS_seq; +DROP SEQUENCE TEMPLATES_seq; +DROP SEQUENCE TICKETCUSTOMFIELDVALUES_seq; +DROP SEQUENCE TICKETS_seq; +DROP SEQUENCE TRANSACTIONS_seq; +DROP SEQUENCE USERS_seq; diff --git a/rt/etc/initialdata b/rt/etc/initialdata index 62b35ace2..e360c5daf 100644 --- a/rt/etc/initialdata +++ b/rt/etc/initialdata @@ -307,7 +307,7 @@ This is a comment. It is not sent to the Requestor(s): Queue => '0', Name => 'Resolved', # loc Description => 'Ticket Resolved', # loc - Content => 'Subject: Ticket Resolved + Content => 'Subject: Resolved: {$Ticket->Subject} According to our records, your request has been resolved. If you have any further questions or concerns, please respond to this message. @@ -551,7 +551,7 @@ while (my $link = $links->Next) { require RT::Action::Notify; bless($self, 'RT::Action::Notify'); $self->{Argument} = 'Requestor'; $self->Prepare; -return $passed; +return 0; # ignore $passed; # ------------------------------------------------------------------- # ], CustomCommitCode => '"never needed"', diff --git a/rt/etc/schema.Informix b/rt/etc/schema.Informix new file mode 100644 index 000000000..ca6173f36 --- /dev/null +++ b/rt/etc/schema.Informix @@ -0,0 +1,342 @@ +-- This schema was adopted from the oracle schema by +-- Andre Koppel. +-- Version 0.2 Date 2003.10.21 +-- The work is still in progress + +CREATE TABLE Attachments ( + id SERIAL, + TransactionId INTEGER NOT NULL, + Parent INTEGER DEFAULT 0 NOT NULL, + MessageId VARCHAR(160), + Subject VARCHAR(255), + Filename VARCHAR(255), + ContentType VARCHAR(80), + ContentEncoding VARCHAR(80), + Content BYTE, + Headers BYTE, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); +CREATE INDEX Attachments1 ON Attachments (Parent); +CREATE INDEX Attachments2 ON Attachments (TransactionId); +CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId); + + +CREATE TABLE Queues ( + id SERIAL, + Name VARCHAR(200) DEFAULT '' NOT NULL, + Description VARCHAR(255) DEFAULT NULL, + CorrespondAddress VARCHAR(120) DEFAULT NULL, + CommentAddress VARCHAR(120) DEFAULT NULL, + InitialPriority INTEGER DEFAULT 0 NOT NULL, + FinalPriority INTEGER DEFAULT 0 NOT NULL, + DefaultDueIn INTEGER DEFAULT 0 NOT NULL, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + Disabled INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX Queues1 ON Queues (Name); +CREATE INDEX Queues2 ON Queues (Disabled); + + +CREATE TABLE Links ( + id SERIAL, + Base VARCHAR(240) DEFAULT NULL, + Target VARCHAR(240) DEFAULT NULL, + Type VARCHAR(20) DEFAULT '' NOT NULL, + LocalTarget INTEGER DEFAULT 0 NOT NULL, + LocalBase INTEGER DEFAULT 0 NOT NULL, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); +-- CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type); +CREATE INDEX Links2 ON Links (Base, Type); +CREATE INDEX Links3 ON Links (Target, Type); +CREATE INDEX Links4 ON Links(Type,LocalBase); + + +CREATE TABLE Principals ( + id SERIAL, + PrincipalType VARCHAR(16) DEFAULT '' NOT NULL, + ObjectId INTEGER DEFAULT 0, + Disabled INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY (id) +); +CREATE INDEX Principals2 ON Principals (ObjectId); + + +CREATE TABLE Groups ( + id SERIAL, + Name VARCHAR(200) DEFAULT NULL, + Description VARCHAR(255) DEFAULT NULL, + Domain VARCHAR(64) DEFAULT '', + Type VARCHAR(64) DEFAULT '', + Instance INTEGER DEFAULT 0 NOT NULL, +-- Instance VARCHAR(64) DEFAULT '' NOT NULL, + PRIMARY KEY (id) +); +CREATE INDEX Groups1 ON Groups (Domain, Instance, Type, id); +CREATE INDEX Groups2 ON Groups (Type, Instance, Domain); + + +CREATE TABLE ScripConditions ( + id SERIAL, + Name VARCHAR(200), + Description VARCHAR(255), + ExecModule VARCHAR(60), + Argument VARCHAR(255), + ApplicableTransTypes VARCHAR(60), + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); + + +CREATE TABLE Transactions ( + id SERIAL, + EffectiveTicket INTEGER DEFAULT 0 NOT NULL, + Ticket INTEGER DEFAULT 0 NOT NULL, + TimeTaken INTEGER DEFAULT 0 NOT NULL, + Type VARCHAR(20), + Field VARCHAR(40), + OldValue VARCHAR(255), + NewValue VARCHAR(255), + Data VARCHAR(255), + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); +CREATE INDEX Transactions1 ON Transactions (Ticket); +CREATE INDEX Transactions2 ON Transactions (EffectiveTicket); + + +CREATE TABLE Scrips ( + id SERIAL, + Description VARCHAR(255) DEFAULT '', + ScripCondition INTEGER DEFAULT 0 NOT NULL, + ScripAction INTEGER DEFAULT 0 NOT NULL, + ConditionRules BYTE, + ActionRules BYTE, + CustomIsApplicableCode BYTE, + CustomPrepareCode BYTE, + CustomCommitCode BYTE, + Stage VARCHAR(32), + Queue INTEGER DEFAULT 0 NOT NULL, + Template INTEGER DEFAULT 0 NOT NULL, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); + + +CREATE TABLE ACL ( + id SERIAL, + PrincipalType VARCHAR(25) NOT NULL, + PrincipalId INTEGER NOT NULL, + RightName VARCHAR(25) NOT NULL, + ObjectType VARCHAR(25) NOT NULL, + ObjectId INTEGER DEFAULT 0 NOT NULL, + DelegatedBy INTEGER DEFAULT 0 NOT NULL, + DelegatedFrom INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY (id) +); +CREATE INDEX ACL1 ON ACL(RightName, ObjectType, ObjectId, PrincipalType, PrincipalId); + + +CREATE TABLE GroupMembers ( + id SERIAL, + GroupId INTEGER DEFAULT 0 NOT NULL, + MemberId INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers (GroupId, MemberId); + + +CREATE TABLE CachedGroupMembers ( + id SERIAL, + GroupId INTEGER DEFAULT 0, + MemberId INTEGER DEFAULT 0, + Via INTEGER DEFAULT 0, + ImmediateParentId INTEGER DEFAULT 0, + Disabled INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY (id) +); +CREATE INDEX DisGrouMem ON CachedGroupMembers (GroupId, MemberId, Disabled); +CREATE INDEX GrouMem ON CachedGroupMembers (GroupId, MemberId); + + +CREATE TABLE Users ( + id SERIAL, + Name VARCHAR(200) NOT NULL, + Password VARCHAR(40), + Comments BYTE, + Signature BYTE, + EmailAddress VARCHAR(120), + FreeFormContactInfo BYTE, + Organization VARCHAR(200), + RealName VARCHAR(120), + NickName VARCHAR(16), + Lang VARCHAR(16), + EmailEncoding VARCHAR(16), + WebEncoding VARCHAR(16), + ExternalContactInfoId VARCHAR(100), + ContactInfoSystem VARCHAR(30), + ExternalAuthId VARCHAR(100), + AuthSystem VARCHAR(30), + Gecos VARCHAR(16), + HomePhone VARCHAR(30), + WorkPhone VARCHAR(30), + MobilePhone VARCHAR(30), + PagerPhone VARCHAR(30), + Address1 VARCHAR(200), + Address2 VARCHAR(200), + City VARCHAR(100), + State VARCHAR(100), + Zip VARCHAR(16), + Country VARCHAR(50), + Timezone VARCHAR(50), + PGPKey BYTE, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); +-- CREATE UNIQUE INDEX Users1 ON Users (Name); +CREATE INDEX Users2 ON Users (Name); +CREATE INDEX Users3 ON Users (id, EmailAddress); +CREATE INDEX Users4 ON Users (EmailAddress); + + +CREATE TABLE Tickets ( + id SERIAL, + EffectiveId INTEGER DEFAULT 0 NOT NULL, + Queue INTEGER DEFAULT 0 NOT NULL, + Type VARCHAR(16), + IssueStatement INTEGER DEFAULT 0 NOT NULL, + Resolution INTEGER DEFAULT 0 NOT NULL, + Owner INTEGER DEFAULT 0 NOT NULL, + Subject VARCHAR(200) DEFAULT '[no subject]', + InitialPriority INTEGER DEFAULT 0 NOT NULL, + FinalPriority INTEGER DEFAULT 0 NOT NULL, + Priority INTEGER DEFAULT 0 NOT NULL, + TimeEstimated INTEGER DEFAULT 0 NOT NULL, + TimeWorked INTEGER DEFAULT 0 NOT NULL, + Status VARCHAR(10), + TimeLeft INTEGER DEFAULT 0 NOT NULL, + Told DATETIME YEAR TO SECOND, + Starts DATETIME YEAR TO SECOND, + Started DATETIME YEAR TO SECOND, + Due DATETIME YEAR TO SECOND, + Resolved DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + Disabled INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY (id) +); +CREATE INDEX Tickets1 ON Tickets (Queue, Status); +CREATE INDEX Tickets2 ON Tickets (Owner); +CREATE INDEX Tickets3 ON Tickets (EffectiveId); +CREATE INDEX Tickets4 ON Tickets (id, Status); +CREATE INDEX Tickets5 ON Tickets (id, EffectiveId); +CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type); + + +CREATE TABLE ScripActions ( + id SERIAL, + Name VARCHAR(200), + Description VARCHAR(255), + ExecModule VARCHAR(60), + Argument VARCHAR(255), + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); + + +CREATE TABLE Templates ( + id SERIAL, + Queue INTEGER DEFAULT 0 NOT NULL, + Name VARCHAR(200) NOT NULL, + Description VARCHAR(255), + Type VARCHAR(16), + Language VARCHAR(16), + TranslationOf INTEGER DEFAULT 0 NOT NULL, + Content BYTE, + LastUpdated DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); + + +CREATE TABLE TicketCustomFieldValues ( + id SERIAL, + Ticket INTEGER NOT NULL, + CustomField INTEGER NOT NULL, + Content VARCHAR(255), + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); + +CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); +CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); + +CREATE TABLE CustomFields ( + id SERIAL, + Name VARCHAR(200), + Type VARCHAR(200), + Queue INTEGER DEFAULT 0 NOT NULL, + Description VARCHAR(255), + SortOrder INTEGER DEFAULT 0 NOT NULL, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + Disabled SMALLINT DEFAULT 0 NOT NULL, + PRIMARY KEY (id) +); +CREATE INDEX CustomFields1 ON CustomFields (Disabled, Queue); + + +CREATE TABLE CustomFieldValues ( + id SERIAL, + CustomField INTEGER NOT NULL, + Name VARCHAR(200), + Description VARCHAR(255), + SortOrder INTEGER DEFAULT 0 NOT NULL, + Creator INTEGER DEFAULT 0 NOT NULL, + Created DATETIME YEAR TO SECOND, + LastUpdatedBy INTEGER DEFAULT 0 NOT NULL, + LastUpdated DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); + +CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); + +CREATE TABLE sessions ( + id VARCHAR(32) NOT NULL, + a_session BYTE, + LastUpdated DATETIME YEAR TO SECOND, + PRIMARY KEY (id) +); + diff --git a/rt/etc/schema.Oracle b/rt/etc/schema.Oracle index 0c14cb39d..95cfda2fd 100644 --- a/rt/etc/schema.Oracle +++ b/rt/etc/schema.Oracle @@ -1,202 +1,198 @@ -CREATE SEQUENCE KEYWORDSELECTS_seq; -CREATE TABLE KeywordSelects ( - id NUMBER(11, 0) PRIMARY KEY, - Name VARCHAR2(255), - Keyword NUMBER(11, 0), - Single NUMBER(11, 0), - Depth NUMBER(11, 0) DEFAULT 0, - ObjectType VARCHAR2(32) NOT NULL, - ObjectField VARCHAR2(32), - ObjectValue VARCHAR2(255), - Disabled NUMBER(11, 0) DEFAULT 0 -); - -CREATE INDEX KeywordSelects1 ON KeywordSelects (Keyword); -CREATE INDEX KeywordSelects2 ON - KeywordSelects(ObjectType, ObjectField, ObjectValue); - - CREATE SEQUENCE ATTACHMENTS_seq; CREATE TABLE Attachments ( - id NUMBER(11,0) PRIMARY KEY, + id NUMBER(11,0) + CONSTRAINT Attachments_Key PRIMARY KEY, TransactionId NUMBER(11,0) NOT NULL, - Parent NUMBER(11,0), + Parent NUMBER(11,0) DEFAULT 0 NOT NULL, MessageId VARCHAR2(160), Subject VARCHAR2(255), Filename VARCHAR2(255), ContentType VARCHAR2(80), - ContentEncoding VARCHAR2(80), + ContentEncoding VARCHAR2(80), Content CLOB, Headers CLOB, - Creator NUMBER(11,0), - Created DATE, - Disabled NUMBER(11,0) DEFAULT 0 + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE ); +CREATE INDEX Attachments2 ON Attachments (TransactionId); +CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId); + CREATE SEQUENCE QUEUES_seq; CREATE TABLE Queues ( - id NUMBER(11, 0) PRIMARY KEY, - Name VARCHAR2(40) NOT NULL UNIQUE, - Description VARCHAR2(120), - CorrespondAddress VARCHAR2(40), - CommentAddress VARCHAR2(40), - InitialPriority NUMBER(11, 0), - FinalPriority NUMBER(11, 0), - DefaultDueIn NUMBER(11, 0), - Creator NUMBER(11, 0), - Created DATE, - LastUpdatedBy NUMBER(11, 0), - LastUpdated DATE, - Disabled NUMBER(11,0) DEFAULT 0 + id NUMBER(11,0) + CONSTRAINT Queues_Key PRIMARY KEY, + Name VARCHAR2(200) CONSTRAINT Queues_Name_Unique UNIQUE NOT NULL, + Description VARCHAR2(255), + CorrespondAddress VARCHAR2(120), + CommentAddress VARCHAR2(120), + InitialPriority NUMBER(11,0) DEFAULT 0 NOT NULL, + FinalPriority NUMBER(11,0) DEFAULT 0 NOT NULL, + DefaultDueIn NUMBER(11,0) DEFAULT 0 NOT NULL, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE, + Disabled NUMBER(11,0) DEFAULT 0 NOT NULL ); + CREATE INDEX Queues1 ON Queues (lower(Name)); +CREATE INDEX Queues2 ON Queues (Disabled); + CREATE SEQUENCE LINKS_seq; CREATE TABLE Links ( - id NUMBER(11,0) PRIMARY KEY, - Base VARCHAR2(255), - Target VARCHAR2(255), + id NUMBER(11,0) + CONSTRAINT Links_Key PRIMARY KEY, + Base VARCHAR2(240), + Target VARCHAR2(240), Type VARCHAR2(20) NOT NULL, - LocalTarget NUMBER(11,0), - LocalBase NUMBER(11,0), - LastUpdatedBy NUMBER(11,0), + LocalTarget NUMBER(11,0) DEFAULT 0 NOT NULL, + LocalBase NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, LastUpdated DATE, - Creator NUMBER(11,0), + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, Created DATE ); - CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type); - +CREATE INDEX Links2 ON Links (Base, Type); +CREATE INDEX Links3 ON Links (Target, Type); +CREATE INDEX Links4 ON Links(Type,LocalBase); + + +CREATE SEQUENCE PRINCIPALS_seq; +CREATE TABLE Principals ( + id NUMBER(11,0) + CONSTRAINT Principals_Key PRIMARY KEY, + PrincipalType VARCHAR2(16), + ObjectId NUMBER(11,0), + Disabled NUMBER(11,0) DEFAULT 0 NOT NULL +); +CREATE UNIQUE INDEX Principals2 ON Principals (ObjectId); CREATE SEQUENCE GROUPS_seq; CREATE TABLE Groups ( - id NUMBER(11,0) PRIMARY KEY, - Name VARCHAR2(16) UNIQUE, - Description VARCHAR(64), - Pseudo NUMBER(11,0) DEFAULT 0 -); - -CREATE SEQUENCE WATCHERS_seq; -CREATE TABLE Watchers ( - id NUMBER(11,0) PRIMARY KEY, - Type VARCHAR2(16), - Scope VARCHAR2(16), - Value NUMBER(11,0), - Email VARCHAR2(255), - Quiet NUMBER(11,0), - Owner NUMBER(11,0), - Creator NUMBER(11,0), - Created DATE, - LastUpdatedBy NUMBER(11,0), - LastUpdated DATE + id NUMBER(11,0) + CONSTRAINT Groups_Key PRIMARY KEY, + Name VARCHAR2(200), + Description VARCHAR2(255), + Domain VARCHAR2(64), + Type VARCHAR2(64), + Instance NUMBER(11,0) DEFAULT 0 -- NOT NULL +-- Instance VARCHAR2(64) ); - +CREATE INDEX Groups1 ON Groups (lower( Domain), Instance, lower(Type), id); +CREATE INDEX Groups2 ON Groups (lower(Type), Instance, lower(Domain)); CREATE SEQUENCE SCRIPCONDITIONS_seq; CREATE TABLE ScripConditions ( - id NUMBER(11, 0) PRIMARY KEY, - Name VARCHAR2(255), + id NUMBER(11, 0) + CONSTRAINT ScripConditions_Key PRIMARY KEY, + Name VARCHAR2(200), Description VARCHAR2(255), ExecModule VARCHAR2(60), Argument VARCHAR2(255), ApplicableTransTypes VARCHAR2(60), - Creator NUMBER(11, 0), + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, Created DATE, - LastUpdatedBy NUMBER(11, 0), + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, LastUpdated DATE ); CREATE SEQUENCE TRANSACTIONS_seq; CREATE TABLE Transactions ( - id NUMBER(11,0) PRIMARY KEY, - EffectiveTicket NUMBER(11,0), - Ticket NUMBER(11,0), - TimeTaken NUMBER(11,0), + id NUMBER(11,0) + CONSTRAINT Transactions_Key PRIMARY KEY, + EffectiveTicket NUMBER(11,0) DEFAULT 0 NOT NULL, + Ticket NUMBER(11,0) DEFAULT 0 NOT NULL, + TimeTaken NUMBER(11,0) DEFAULT 0 NOT NULL, Type VARCHAR2(20), Field VARCHAR2(40), OldValue VARCHAR2(255), NewValue VARCHAR2(255), - Data VARCHAR2(100), - Creator NUMBER(11,0), - Created DATE, - Disabled NUMBER(11,0) DEFAULT 0 + Data VARCHAR2(255), + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE ); +CREATE INDEX Transactions1 ON Transactions (Ticket); +CREATE INDEX Transactions2 ON Transactions (EffectiveTicket); + CREATE SEQUENCE SCRIPS_seq; CREATE TABLE Scrips ( - id NUMBER(11,0) PRIMARY KEY, - ScripCondition NUMBER(11,0), - ScripAction NUMBER(11,0), + id NUMBER(11,0) + CONSTRAINT Scrips_Key PRIMARY KEY, + Description VARCHAR2(255), + ScripCondition NUMBER(11,0) DEFAULT 0 NOT NULL, + ScripAction NUMBER(11,0) DEFAULT 0 NOT NULL, + ConditionRules CLOB, + ActionRules CLOB, + CustomIsApplicableCode CLOB, + CustomPrepareCode CLOB, + CustomCommitCode CLOB, Stage VARCHAR2(32), - Queue NUMBER(11,0), - Template NUMBER(11,0), - Creator NUMBER(11,0), + Queue NUMBER(11,0) DEFAULT 0 NOT NULL, + Template NUMBER(11,0) DEFAULT 0 NOT NULL, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, Created DATE, - LastUpdatedBy NUMBER(11,0), + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, LastUpdated DATE ); - - CREATE SEQUENCE ACL_seq; CREATE TABLE ACL ( - id NUMBER(11,0) PRIMARY KEY, - PrincipalId NUMBER(11,0), - PrincipalType VARCHAR2(25), - RightName VARCHAR2(25), - RightScope VARCHAR2(25), - RightAppliesTo NUMBER(11,0) + id NUMBER(11,0) + CONSTRAINT ACL_Key PRIMARY KEY, + PrincipalType VARCHAR2(25) NOT NULL, + PrincipalId NUMBER(11,0) NOT NULL, + RightName VARCHAR2(25) NOT NULL, + ObjectType VARCHAR2(25) NOT NULL, + ObjectId NUMBER(11,0) DEFAULT 0 NOT NULL, + DelegatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + DelegatedFrom NUMBER(11,0) DEFAULT 0 NOT NULL ); +CREATE INDEX ACL1 ON ACL(RightName, ObjectType, ObjectId, PrincipalType, PrincipalId); + CREATE SEQUENCE GROUPMEMBERS_seq; CREATE TABLE GroupMembers ( - id NUMBER(11,0) PRIMARY KEY, - GroupId NUMBER(11,0), - UserId NUMBER(11,0) + id NUMBER(11,0) + CONSTRAINT GroupMembers_Key PRIMARY KEY, + GroupId NUMBER(11,0) DEFAULT 0 NOT NULL, + MemberId NUMBER(11,0) DEFAULT 0 NOT NULL ); - -CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers (GroupId, UserId); - - -CREATE SEQUENCE OBJECTKEYWORDS_seq; -CREATE TABLE ObjectKeywords ( - id NUMBER(11,0) PRIMARY KEY, - Keyword NUMBER(11,0) NOT NULL, - KeywordSelect NUMBER(11,0) NOT NULL, - ObjectType VARCHAR2(32) NOT NULL, - ObjectId NUMBER(11,0) NOT NULL -); - -CREATE UNIQUE INDEX ObjectKeywords1 ON ObjectKeywords - (ObjectId, ObjectType, KeywordSelect, Keyword); -CREATE INDEX ObjectKeywords3 ON ObjectKeywords (Keyword); - -CREATE SEQUENCE KEYWORDS_seq; -CREATE TABLE Keywords ( - id NUMBER(11, 0) PRIMARY KEY, - Name VARCHAR2(255) NOT NULL, - Description VARCHAR2(255), - Parent NUMBER(11, 0), - Disabled NUMBER(11, 0) DEFAULT 0 +CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers (GroupId, MemberId); + + +CREATE SEQUENCE CachedGroupMembers_seq; +CREATE TABLE CachedGroupMembers ( + id NUMBER(11,0) + CONSTRAINT CachedGroupMembers_Key PRIMARY KEY, + GroupId NUMBER(11,0), + MemberId NUMBER(11,0), + Via NUMBER(11,0), + ImmediateParentId NUMBER(11,0), + Disabled NUMBER(11,0) DEFAULT 0 NOT NULL ); +CREATE INDEX DisGrouMem ON CachedGroupMembers (GroupId, MemberId, Disabled); +CREATE INDEX GrouMem ON CachedGroupMembers (GroupId, MemberId); -CREATE UNIQUE INDEX Keywords1 ON Keywords (Name, Parent); -CREATE INDEX Keywords3 ON Keywords (Parent); CREATE SEQUENCE USERS_seq; CREATE TABLE Users ( - id NUMBER(11,0) PRIMARY KEY, - Name VARCHAR2(120) NOT NULL UNIQUE, + id NUMBER(11,0) + CONSTRAINT Users_Key PRIMARY KEY, + Name VARCHAR2(200) CONSTRAINT Users_Name_Unique + unique NOT NULL, Password VARCHAR2(40), Comments CLOB, Signature CLOB, EmailAddress VARCHAR2(120), FreeFormContactInfo CLOB, Organization VARCHAR2(200), - Privileged NUMBER(11,0), RealName VARCHAR2(120), NickName VARCHAR2(16), Lang VARCHAR2(16), @@ -217,71 +213,142 @@ CREATE TABLE Users ( State VARCHAR2(100), Zip VARCHAR2(16), Country VARCHAR2(50), - Creator NUMBER(11,0), + Timezone VARCHAR2(50), + PGPKey CLOB, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, Created DATE, - LastUpdatedBy NUMBER(11,0), - LastUpdated DATE, - Disabled NUMBER(11,0) DEFAULT 0 + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE ); +-- CREATE UNIQUE INDEX Users1 ON Users (Name); - +CREATE INDEX Users2 ON Users( LOWER(name)); +CREATE INDEX Users4 ON Users (lower(EmailAddress)); CREATE SEQUENCE TICKETS_seq; CREATE TABLE Tickets ( - id NUMBER(11, 0) PRIMARY KEY, - EffectiveId NUMBER(11, 0), - Queue NUMBER(11,0), + id NUMBER(11, 0) + CONSTRAINT Tickets_Key PRIMARY KEY, + EffectiveId NUMBER(11,0) DEFAULT 0 NOT NULL, + Queue NUMBER(11,0) DEFAULT 0 NOT NULL, Type VARCHAR2(16), - IssueStatement NUMBER(11,0), - Resolution NUMBER(11,0), - Owner NUMBER(11,0), - Subject VARCHAR2(200) DEFAULT '', - InitialPriority NUMBER(11,0) DEFAULT 0, - FinalPriority NUMBER(11,0) DEFAULT 0, - Priority NUMBER(11,0) DEFAULT 0, + IssueStatement NUMBER(11,0) DEFAULT 0 NOT NULL, + Resolution NUMBER(11,0) DEFAULT 0 NOT NULL, + Owner NUMBER(11,0) DEFAULT 0 NOT NULL, + Subject VARCHAR2(200) DEFAULT '[no subject]', + InitialPriority NUMBER(11,0) DEFAULT 0 NOT NULL, + FinalPriority NUMBER(11,0) DEFAULT 0 NOT NULL, + Priority NUMBER(11,0) DEFAULT 0 NOT NULL, + TimeEstimated NUMBER(11,0) DEFAULT 0 NOT NULL, + TimeWorked NUMBER(11,0) DEFAULT 0 NOT NULL, Status VARCHAR2(10), - TimeWorked NUMBER(11,0) DEFAULT 0, - TimeLeft NUMBER(11,0) DEFAULT 0, + TimeLeft NUMBER(11,0) DEFAULT 0 NOT NULL, Told DATE, Starts DATE, Started DATE, Due DATE, Resolved DATE, - LastUpdatedBy NUMBER(11,0), + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, LastUpdated DATE, - Creator NUMBER(11,0), + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, Created DATE, - Disabled NUMBER(11,0) DEFAULT 0 + Disabled NUMBER(11,0) DEFAULT 0 NOT NULL ); +CREATE INDEX Tickets1 ON Tickets (Queue, Status); +CREATE INDEX Tickets2 ON Tickets (Owner); +CREATE INDEX Tickets4 ON Tickets (id, Status); +CREATE INDEX Tickets5 ON Tickets (id, EffectiveId); +CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type); + CREATE SEQUENCE SCRIPACTIONS_seq; CREATE TABLE ScripActions ( - id NUMBER(11,0) PRIMARY KEY, - Name VARCHAR2(255), + id NUMBER(11,0) + CONSTRAINT ScripActions_Key PRIMARY KEY, + Name VARCHAR2(200), Description VARCHAR2(255), ExecModule VARCHAR2(60), Argument VARCHAR2(255), - Creator NUMBER(11,0), + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, Created DATE, - LastUpdatedBy NUMBER(11,0), + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, LastUpdated DATE ); CREATE SEQUENCE TEMPLATES_seq; CREATE TABLE Templates ( - id NUMBER(11,0) PRIMARY KEY, + id NUMBER(11,0) + CONSTRAINT Templates_Key PRIMARY KEY, Queue NUMBER(11,0) DEFAULT 0 NOT NULL, - Name VARCHAR2(40) NOT NULL UNIQUE, - Description VARCHAR2(120), + Name VARCHAR2(200) NOT NULL, + Description VARCHAR2(255), Type VARCHAR2(16), Language VARCHAR2(16), - TranslationOf NUMBER(11,0), + TranslationOf NUMBER(11,0) DEFAULT 0 NOT NULL, Content CLOB, LastUpdated DATE, - LastUpdatedBy NUMBER(11,0), - Creator NUMBER(11,0), + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, Created DATE ); + +CREATE SEQUENCE TICKETCUSTOMFIELDVALUES_seq; +CREATE TABLE TicketCustomFieldValues ( + id NUMBER(11,0) + CONSTRAINT TicketCustomFieldValues_Key PRIMARY KEY, + Ticket NUMBER(11,0), + CustomField NUMBER(11,0) NOT NULL, + Content VARCHAR2(255), + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE +); + +CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); +CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); + +CREATE SEQUENCE CUSTOMFIELDS_seq; +CREATE TABLE CustomFields ( + id NUMBER(11,0) + CONSTRAINT CustomFields_Key PRIMARY KEY, + Name VARCHAR2(200), + Type VARCHAR2(200), + Queue NUMBER(11,0) DEFAULT 0 NOT NULL, + Description VARCHAR2(255), + SortOrder NUMBER(11,0) DEFAULT 0 NOT NULL, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE, + Disabled NUMBER(11,0) DEFAULT 0 NOT NULL +); +CREATE INDEX CustomFields1 ON CustomFields (Disabled, Queue); + + +CREATE SEQUENCE CUSTOMFIELDVALUES_seq; +CREATE TABLE CustomFieldValues ( + id NUMBER(11,0) + CONSTRAINT CustomFieldValues_Key PRIMARY KEY, + CustomField NUMBER(11,0), + Name VARCHAR2(200), + Description VARCHAR2(255), + SortOrder NUMBER(11,0) DEFAULT 0 NOT NULL, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE +); + +CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); + +CREATE TABLE sessions ( + id VARCHAR2(32) + CONSTRAINT Sessions_Key PRIMARY KEY, + a_session CLOB, + LastUpdated DATE +); + diff --git a/rt/etc/schema.Pg b/rt/etc/schema.Pg index ba0d6fc6c..085c61595 100755 --- a/rt/etc/schema.Pg +++ b/rt/etc/schema.Pg @@ -3,9 +3,6 @@ -- ------------------------------------------------------------------ -BEGIN; - - -- @@ -93,6 +90,7 @@ CREATE TABLE Links ( ); CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type) ; +CREATE INDEX Links4 ON Links(Type,LocalBase); -- }}} @@ -136,7 +134,7 @@ CREATE TABLE Groups ( Description varchar(255) NULL , Domain varchar(64), Type varchar(64), - Instance varchar(64), + Instance integer, PRIMARY KEY (id) ); @@ -192,7 +190,7 @@ CREATE TABLE Transactions ( Field varchar(40) NULL , OldValue varchar(255) NULL , NewValue varchar(255) NULL , - Data varchar(100) NULL , + Data varchar(255) NULL , Creator integer NOT NULL DEFAULT 0 , Created TIMESTAMP NULL , @@ -500,6 +498,9 @@ CREATE TABLE TicketCustomFieldValues ( ); +CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); +CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); + -- }}} -- {{{ CustomFields @@ -556,6 +557,8 @@ CREATE TABLE CustomFieldValues ( ); +CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); + -- }}} -- {{{ Sessions @@ -573,6 +576,3 @@ CREATE TABLE sessions ( -- }}} - - -COMMIT; diff --git a/rt/etc/schema.SQLite b/rt/etc/schema.SQLite index f24bdbdc1..b10ff46d1 100644 --- a/rt/etc/schema.SQLite +++ b/rt/etc/schema.SQLite @@ -58,6 +58,7 @@ CREATE TABLE Links ( ) ; CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type) ; +CREATE INDEX Links4 ON Links(Type,LocalBase); --- }}} @@ -81,7 +82,7 @@ CREATE TABLE Groups ( Description varchar(255) NULL , Domain varchar(64), Type varchar(64), - Instance varchar(64) + Instance integer ) ; @@ -118,7 +119,7 @@ CREATE TABLE Transactions ( Field varchar(40) NULL , OldValue varchar(255) NULL , NewValue varchar(255) NULL , - Data varchar(100) NULL , + Data varchar(255) NULL , Creator integer NULL , Created DATETIME NULL @@ -343,6 +344,9 @@ CREATE TABLE TicketCustomFieldValues ( ) ; +CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); +CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); + --- }}} --- {{{ CustomFields @@ -381,4 +385,6 @@ CREATE TABLE CustomFieldValues ( ) ; +CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); + --- }}} diff --git a/rt/etc/schema.mysql b/rt/etc/schema.mysql index 46f8ec562..14e92238f 100755 --- a/rt/etc/schema.mysql +++ b/rt/etc/schema.mysql @@ -62,6 +62,7 @@ CREATE TABLE Links ( CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type) ; CREATE INDEX Links2 ON Links (Base, Type) ; CREATE INDEX Links3 ON Links (Target, Type) ; +CREATE INDEX Links4 ON Links(Type,LocalBase); # }}} @@ -87,7 +88,7 @@ CREATE TABLE Groups ( Description varchar(255) NULL , Domain varchar(64), Type varchar(64), - Instance varchar(64), + Instance integer, PRIMARY KEY (id) ) TYPE=InnoDB; @@ -125,7 +126,7 @@ CREATE TABLE Transactions ( Field varchar(40) NULL , OldValue varchar(255) NULL , NewValue varchar(255) NULL , - Data varchar(100) NULL , + Data varchar(255) NULL , Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -358,6 +359,9 @@ CREATE TABLE TicketCustomFieldValues ( PRIMARY KEY (id) ) TYPE=InnoDB; +CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); +CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); + # }}} # {{{ CustomFields @@ -399,6 +403,8 @@ CREATE TABLE CustomFieldValues ( PRIMARY KEY (id) ) TYPE=InnoDB; +CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); + # }}} # {{{ Sessions diff --git a/rt/html/Admin/Elements/EditCustomField b/rt/html/Admin/Elements/EditCustomField index a09600ba7..7baed168b 100644 --- a/rt/html/Admin/Elements/EditCustomField +++ b/rt/html/Admin/Elements/EditCustomField @@ -24,7 +24,7 @@ <& /Elements/ListActions, actions => \@results &> -<FORM METHOD=GET ACTION="CustomField.html"> +<FORM METHOD=POST ACTION="CustomField.html"> <INPUT TYPE=HIDDEN NAME="CustomField" VALUE="<%$id %>"> <INPUT TYPE=HIDDEN name="Queue" value="<%$Queue%>"> diff --git a/rt/html/Admin/Elements/EditCustomFieldValues b/rt/html/Admin/Elements/EditCustomFieldValues index 64564adfb..2c9e6d082 100644 --- a/rt/html/Admin/Elements/EditCustomFieldValues +++ b/rt/html/Admin/Elements/EditCustomFieldValues @@ -25,7 +25,7 @@ <ul> % while (my $v = $values->Next) { <li> -<font size=-1 color="#336699"><%$v->SortOrder%>:</font> +<INPUT TYPE="text" SIZE="2" NAME="CustomField-<%$CustomField->Id%>-SortOrder<%$v->Id()%>" VALUE="<%$v->SortOrder()%>"> <input type="checkbox" name="CustomField-<%$CustomField->Id%>-DeleteValue" value="<%$v->id%>"> <%$v->Name%> % if ($v->Description) { diff --git a/rt/html/Admin/Elements/EditCustomFields b/rt/html/Admin/Elements/EditCustomFields index a86b051d0..81c984d29 100644 --- a/rt/html/Admin/Elements/EditCustomFields +++ b/rt/html/Admin/Elements/EditCustomFields @@ -26,44 +26,43 @@ <TABLE> <TR> <TD VALIGN=TOP> -<%$caption%>:<BR> +<h2><%$caption%></h2> </TD></TR></TABLE> % if ($CustomFields->Count == 0 ) { <P><i><&|/l&>(No custom fields)</&></i></P> % } else { -<TABLE> - -<TR> -<TD ROWSPAN="<% $CustomFields->Count %>"> -<UL> -% while (my $CustomFieldObj = $CustomFields->Next) { -<LI><A HREF="CustomField.html?Queue=<%$id%>&CustomField=<%$CustomFieldObj->id()%>"><b><%$CustomFieldObj->Name%></b></a> (<% $CustomFieldObj->FriendlyType %>)<br> -<%$CustomFieldObj->Description%> -</LI> -% } -</UL> -</TD> - +<TABLE cellspacing=0 cellpadding=2> % my $count; % while (my $CustomFieldObj = $CustomFields->Next) { +<TR> + <TD valign="TOP"> +% if ($CustomFieldObj->Name) { + <A HREF="CustomField.html?Queue=<%$id%>&CustomField=<%$CustomFieldObj->id()%>"><b><%$CustomFieldObj->Name%></b></a><br> +% } else { + <A HREF="CustomField.html?Queue=<%$id%>&CustomField=<%$CustomFieldObj->id()%>"><i>(<%loc("no name")%>)</i></a><br> +% } + <%$CustomFieldObj->Description%> + </TD> + <TD valign="TOP"> + <i><% $CustomFieldObj->FriendlyType %></i> + </TD> % # show 'move up' unless it's the first item % if ($count++) { -<TR><TD> -<a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=-1"><&|/l&>Move up</&></a> + <TD valign="TOP"> + <a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=-1"><&|/l&>Move up</&></a> % } else { -<TD ALIGN=RIGHT> + <TD valign="TOP" ALIGN=RIGHT> % } % # show 'move down' unless it's the last item % if (!$CustomFields->IsLast) { % $m->print(' | ') if $count > 1; -<a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=1"><&|/l&>Move down</&></a> + <a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=1"><&|/l&>Move down</&></a> % } -</TD></TR> -% } - </TD> </TR> +% } + </TABLE> % } <FORM METHOD=GET ACTION="CustomFields.html"> diff --git a/rt/html/Admin/Elements/EditScrip b/rt/html/Admin/Elements/EditScrip index 5393ebfde..1f186c233 100644 --- a/rt/html/Admin/Elements/EditScrip +++ b/rt/html/Admin/Elements/EditScrip @@ -77,6 +77,14 @@ </TR> <TR> <TD ALIGN=RIGHT> +<&|/l&>Stage</&>: +</TD> +<TD> +<& /Admin/Elements/SelectStage, Name => "Scrip-$id-Stage", Default => $scrip->Stage &> +</TD> +</TR> +<TR> +<TD ALIGN=RIGHT> <&|/l&>Template</&>: </TD> <TD> @@ -123,6 +131,7 @@ elsif ($id) { ScripAction ScripCondition Template + Stage Description CustomPrepareCode CustomCommitCode diff --git a/rt/html/Admin/Elements/EditScrips b/rt/html/Admin/Elements/EditScrips index 24515d8c1..07a57f47b 100644 --- a/rt/html/Admin/Elements/EditScrips +++ b/rt/html/Admin/Elements/EditScrips @@ -48,7 +48,9 @@ </TABLE> % } -<& /Elements/Submit &> +<& /Elements/Submit, + Caption => loc("Delete selected scrips"), + Label => loc("Delete") &> </form> <%init> my (@actions); diff --git a/rt/html/Admin/Elements/SelectGroups b/rt/html/Admin/Elements/SelectGroups index 5df49ad04..3cc909b29 100644 --- a/rt/html/Admin/Elements/SelectGroups +++ b/rt/html/Admin/Elements/SelectGroups @@ -29,9 +29,10 @@ <%INIT> my $groups = new RT::Groups($session{'CurrentUser'}); -$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'System'); +$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain); </%INIT> <%ARGS> $Name => 'groups' +$Domain => 'UserDefined'; </%ARGS> diff --git a/rt/html/Admin/Elements/SelectRights b/rt/html/Admin/Elements/SelectRights index 37a06dc4d..8d87ac9a1 100644 --- a/rt/html/Admin/Elements/SelectRights +++ b/rt/html/Admin/Elements/SelectRights @@ -24,7 +24,7 @@ <INPUT TYPE=HIDDEN NAME="CheckACL" VALUE="<%$ACLDesc%>"> <TABLE BORDER=0> <TR> -<TD valign=top width="180"> +<TD valign=top width="180" align="left"> <h3><&|/l&>Current rights</&></h3> % if ($ACLObj->Count() > 0) { <i>(<&|/l&>Check box to revoke right</&>)</i> <BR> @@ -71,6 +71,7 @@ $ACLObj->LimitToObject( $Object); $ACLObj->LimitToPrincipal( Id => $PrincipalId); + $ACLObj->OrderBy(FIELD=>'RightName'); if (ref($Object) && UNIVERSAL::can($Object, 'AvailableRights')) { %Rights = %{$Object->AvailableRights}; diff --git a/rt/html/Admin/Elements/SelectStage b/rt/html/Admin/Elements/SelectStage new file mode 100644 index 000000000..b62964be4 --- /dev/null +++ b/rt/html/Admin/Elements/SelectStage @@ -0,0 +1,39 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +<SELECT NAME=<%$Name%>> +% foreach my $stage (qw(TransactionCreate TransactionBatch)) { +<OPTION VALUE=<%$stage%> +<% ($stage eq $Default) && 'SELECTED' %> +><% loc($stage) %> +</OPTION> +% } +<%INIT> +if ($Default eq '') { + $Default = 'TransactionCreate'; +} +</%INIT> +<%ARGS> +$Default => 'TransactionCreate' +$Name => 'Stage' +</%ARGS> diff --git a/rt/html/Admin/Queues/CustomFields.html b/rt/html/Admin/Queues/CustomFields.html index 78c6c2790..ddf39d71a 100644 --- a/rt/html/Admin/Queues/CustomFields.html +++ b/rt/html/Admin/Queues/CustomFields.html @@ -32,7 +32,8 @@ <& /Admin/Elements/EditCustomFields, title => $title, %ARGS &> <%INIT> my $Queue = new RT::Queue($session{'CurrentUser'}); -$Queue->Load($id); +$Queue->Load($id) || Abort(loc("Couldn't load queue", $id)); + my $CustomFields = RT::CustomFields->new($RT::SystemUser); $CustomFields->LimitToQueue($Queue->Id); my $subtabs = { diff --git a/rt/html/Admin/Queues/index.html b/rt/html/Admin/Queues/index.html index f733c25d8..78a1d5d2d 100644 --- a/rt/html/Admin/Queues/index.html +++ b/rt/html/Admin/Queues/index.html @@ -38,7 +38,7 @@ %} </UL> <BR> -<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Queues/"> +<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Queues/index.html"> <input type="checkbox" name="FindDisabledQueues"> <&|/l&>Include disabled queues in listing.</&> <div align=right><input type=submit value="<&|/l&>Go!</&>"></div> </FORM> diff --git a/rt/html/Admin/Users/Modify.html b/rt/html/Admin/Users/Modify.html index 370c2e82d..b424ae961 100644 --- a/rt/html/Admin/Users/Modify.html +++ b/rt/html/Admin/Users/Modify.html @@ -224,9 +224,11 @@ else { } else { push @results, loc('User could not be created: [_1]', $msg); } - - } - else { + + # set the id, so the the menu will have the right info + $id = $UserObj->Id; + + } else { $UserObj->Load($id) || $UserObj->Load($Name) || Abort("Couldn't load user '$Name'"); $val = $UserObj->Id(); } diff --git a/rt/html/Admin/Users/index.html b/rt/html/Admin/Users/index.html index a95d4117d..7dc9af6c3 100644 --- a/rt/html/Admin/Users/index.html +++ b/rt/html/Admin/Users/index.html @@ -40,7 +40,7 @@ </UL> <br><br> -<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Users/"> +<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Users/index.html"> <&|/l&>Find people whose</&> <& /Elements/SelectUsers &><BR> <input type="checkbox" name="FindDisabledUsers"> <&|/l&>Include disabled users in search.</&> diff --git a/rt/html/Approvals/Display.html b/rt/html/Approvals/Display.html index 921c1e38f..6a265e242 100644 --- a/rt/html/Approvals/Display.html +++ b/rt/html/Approvals/Display.html @@ -26,7 +26,7 @@ <& Elements/Tabs, current_tab => "Approvals/Display.html", Title => $title &> -<form method=post action="<%$RT::WebPath%>/Approvals/"> +<form method=post action="<%$RT::WebPath%>/Approvals/index.html"> <& /Elements/TitleBoxStart, title => $title &> <& /Ticket/Elements/ShowHistory , Ticket => $Ticket, Collapsed => 0, ShowTitle => 0, ShowHeaders => 0, ShowDisplayModes => 0, ShowTitleBarCommands => 0 &> diff --git a/rt/html/Elements/Callback b/rt/html/Elements/Callback index 93ac4c01b..79157e751 100644 --- a/rt/html/Elements/Callback +++ b/rt/html/Elements/Callback @@ -54,10 +54,11 @@ if (!$callbacks) { $cache{$Page,$_CallbackName} = $callbacks; } -foreach my $comp (@$callbacks) { - $m->comp($comp, %ARGS) if $m->comp_exists($comp); +my @rv; +foreach my $comp (sort @$callbacks) { + push @rv, $m->comp($comp, %ARGS) if $m->comp_exists($comp); } -return(1); +return @rv; </%init> <%args> $_CallbackName => 'Default' diff --git a/rt/html/Elements/MessageBox b/rt/html/Elements/MessageBox index 64fdf38b7..32f422206 100644 --- a/rt/html/Elements/MessageBox +++ b/rt/html/Elements/MessageBox @@ -21,7 +21,7 @@ %# %# %# END LICENSE BLOCK -<TEXTAREA COLS=<%$Width%> ROWS=15 WRAP=HARD NAME="<%$Name%>"><& /Elements/Callback, %ARGS &><% $Default %><%$message%><%$signature%></TEXTAREA> +<TEXTAREA COLS=<%$Width%> ROWS=15 WRAP=<%$Wrap%> NAME="<%$Name%>"><& /Elements/Callback, %ARGS &><% $Default %><%$message%><%$IncludeSignature ? $signature : ''%></TEXTAREA> <%INIT> my ($message); @@ -42,6 +42,8 @@ if ($session{'CurrentUser'}->UserObj->Signature) { $QuoteTransaction => undef $Name => 'Content' $Default => '' -$Width => 72 +$Width => $RT::MessageBoxWidth +$Wrap => $RT::MessageBoxWrap +$IncludeSignature => 1 </%ARGS> diff --git a/rt/html/Elements/MyTickets b/rt/html/Elements/MyTickets index 6e2ddc6c3..52dae3b8d 100644 --- a/rt/html/Elements/MyTickets +++ b/rt/html/Elements/MyTickets @@ -69,7 +69,7 @@ <%INIT> -my $rows = 10; +my $rows = $RT::MyTicketsLength; my $MyTickets; $MyTickets = new RT::Tickets ($session{'CurrentUser'}); $MyTickets->LimitOwner(VALUE => $session{'CurrentUser'}->Id); diff --git a/rt/html/Elements/SelectLang b/rt/html/Elements/SelectLang new file mode 100644 index 000000000..cc2c357e0 --- /dev/null +++ b/rt/html/Elements/SelectLang @@ -0,0 +1,56 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +<SELECT NAME ="<%$Name%>"> +% if ($ShowNullOption) { +<OPTION VALUE="">-</OPTION> +% } +% foreach my $lang (@lang) { +<OPTION VALUE="<%$lang%>" <%($Default && ($lang eq $Default)) && 'SELECTED'%>><% $lang_to_desc{$lang} %> +% if (($Verbose) and (my $description = I18N::LangTags::List::native_name($lang)) ){ +(<%$description%>) +% } +</OPTION> +% } +</SELECT> +<%ARGS> +$ShowNullOption => 1 +$ShowAllQueues => 1 +$Name => undef +$Verbose => undef +$Default => 0 +$Lite => 0 +</%ARGS> + +<%ONCE> +use I18N::LangTags::List; +my (@lang, %lang_to_desc); +foreach my $lang (map { s/:://; s/_/-/g; $_ } grep { /^\w+::$/ } keys %RT::I18N::) { + next if $lang =~ /i-default|en-us/; + my $desc = I18N::LangTags::List::name($lang); + next unless ($desc); + $desc =~ s/(.*) (.*)/$2 ($1)/; + $lang_to_desc{$lang} = $desc; +} +@lang = sort { $lang_to_desc{$a} cmp $lang_to_desc{$b} } keys %lang_to_desc; +</%ONCE> diff --git a/rt/html/Elements/SelectStatus b/rt/html/Elements/SelectStatus index 2c1ffad39..16a5f2995 100644 --- a/rt/html/Elements/SelectStatus +++ b/rt/html/Elements/SelectStatus @@ -24,6 +24,7 @@ <SELECT NAME ="<%$Name%>"> <OPTION VALUE="">-</OPTION> %foreach my $status (@status) { +%next if ($SkipDeleted && $status eq 'deleted'); <OPTION VALUE="<%$status%>" <%($Default eq $status) && 'SELECTED'%>><%loc($status)%></OPTION> % } </SELECT> @@ -34,4 +35,5 @@ my @status = $queue->StatusArray(); <%ARGS> $Name => undef $Default => undef +$SkipDeleted => 0 </%ARGS> diff --git a/rt/html/Elements/SelectWatcherType b/rt/html/Elements/SelectWatcherType index 26de8f7b9..82aab2a85 100644 --- a/rt/html/Elements/SelectWatcherType +++ b/rt/html/Elements/SelectWatcherType @@ -22,7 +22,9 @@ %# %# END LICENSE BLOCK <SELECT NAME ="<%$Name%>"> +% if ($AllowNull) { <OPTION VALUE="">-</OPTION> +% } %for my $option (@types) { <OPTION VALUE="<%$option%>" <%$option eq $Default && "SELECTED"%>><%loc($option)%></OPTION> %} @@ -38,6 +40,7 @@ else { } </%INIT> <%ARGS> +$AllowNull => 1 $Default=>undef $Scope => 'ticket' $Name => 'WatcherType' diff --git a/rt/html/Elements/SetupSessionCookie b/rt/html/Elements/SetupSessionCookie index 4d728ce70..7a2ad9ff5 100644 --- a/rt/html/Elements/SetupSessionCookie +++ b/rt/html/Elements/SetupSessionCookie @@ -22,18 +22,25 @@ %# %# END LICENSE BLOCK <%init> +return if $m->is_subrequest; # avoid reentrancy, as suggested by masonbook + my %cookies = CGI::Cookie->fetch(); +my $cookiename = "RT_SID_".$RT::rtname.".".$ENV{'SERVER_PORT'}; my %backends = ( mysql => 'Apache::Session::MySQL', Pg => 'Apache::Session::Postgres', - Oracle => 'Apache::Session::Oracle', +# Oracle => 'Apache::Session::Oracle', ) unless $RT::WebSessionClass; my $session_class = $RT::WebSessionClass || $backends{$RT::DatabaseType} || 'Apache::Session::File'; my $pm = "$session_class.pm"; $pm =~ s|::|/|g; require $pm; + # morning bug avoidance attempt -- pdh 20030815 + unless ($RT::Handle->dbh && $RT::Handle->dbh->ping) { + $RT::Handle->Connect(); + } eval { tie %session, $session_class, - $SessionCookie || ( $cookies{'RT_SID'} ? $cookies{'RT_SID'}->value() : undef ), + $SessionCookie || ( $cookies{$cookiename} ? $cookies{$cookiename}->value() : undef ), $backends{$RT::DatabaseType} ? { Handle => $RT::Handle->dbh, LockHandle => $RT::Handle->dbh, @@ -54,22 +61,23 @@ my $pm = "$session_class.pm"; $pm =~ s|::|/|g; require $pm; Directory => $RT::MasonSessionDir, LockDirectory => $RT::MasonSessionDir, }; - undef $cookies{'RT_SID'}; + undef $cookies{$cookiename}; } else { die "RT Couldn't write to session directory '$RT::MasonSessionDir': $@. Check that this dir ectory's permissions are correct."; } } - if ( !$cookies{'RT_SID'} ) { + if ( !$cookies{$cookiename} ) { my $cookie = new CGI::Cookie( - -name => 'RT_SID', + -name => $cookiename, -value => $session{_session_id}, -path => '/', ); $r->header_out('Set-Cookie', $cookie->as_string); } + return(); </%init> <%args> diff --git a/rt/html/Elements/SimpleSearch b/rt/html/Elements/SimpleSearch index 69541f801..4a0d10656 100644 --- a/rt/html/Elements/SimpleSearch +++ b/rt/html/Elements/SimpleSearch @@ -22,6 +22,6 @@ %# %# END LICENSE BLOCK <form action="<% $RT::WebPath %>/index.html"> -<input size="12" name="q" accesskey="0"> +<input size="12" name="q" autocomplete="off" accesskey="0"> <input type="submit" value="<&|/l&>Search</&>"> </form> diff --git a/rt/html/NoAuth/webrt.css b/rt/html/NoAuth/webrt.css index 62c6d66ba..159e79cd6 100644 --- a/rt/html/NoAuth/webrt.css +++ b/rt/html/NoAuth/webrt.css @@ -331,7 +331,9 @@ ul.topnav { margin-bottom:0; } - +<%flags> +inherit => undef +</%flags> <%init> $r->content_type('text/css'); $r->header_out('Expires' ,'+30m'); diff --git a/rt/html/REST/1.0/Forms/queue/default b/rt/html/REST/1.0/Forms/queue/default new file mode 100644 index 000000000..ce5408846 --- /dev/null +++ b/rt/html/REST/1.0/Forms/queue/default @@ -0,0 +1,123 @@ +%# REST/1.0/Forms/queue/default +%# +<%ARGS> +$id +$format => 's' +$changes => {} +</%ARGS> +<%perl> +my @comments; +my ($c, $o, $k, $e) = ("", [], {}, 0); +my %data = %$changes; +my $queue = new RT::Queue $session{CurrentUser}; +my @fields = qw(Name Description CorrespondAddress CommentAddress + InitialPriority FinalPriority DefaultDueIn); +my %fields = map { lc $_ => $_ } @fields; + +if ($id ne 'new') { + $queue->Load($id); + if (!$queue->Id) { + return [ "# Queue $id does not exist.", [], {}, 1 ]; + } +} +else { + if (%data == 0) { + return [ + "# Required: Name", + [ "id", @fields ], + { + id => 'queue/new', + Name => '<queue name>', + Description => "", + CommentAddress => "", + CorrespondAddress => "", + InitialPriority => "", + FinalPriority => "", + DefaultDueIn => "", + }, + 0 + ]; + } + else { + my %v; + my %create = %fields; + + foreach my $k (keys %data) { + if (exists $create{lc $k}) { + $v{$create{lc $k}} = delete $data{$k}; + } + } + + if ($v{Name} eq '<queue name>') { + my %o = keys %$changes; + delete @o{"id", @fields}; + return [ + "# Please set the queue name.", + [ "id", @fields, keys %o ], $changes, 1 + ]; + } + + $queue->Create(%v); + unless ($queue->Id) { + return [ "# Could not create queue.", [], {}, 1 ]; + } + + delete $data{id}; + $id = $queue->Id; + push(@comments, "# Queue $id created."); + goto DONE if %data == 0; + } +} + +if (%data == 0) { + my @data; + + push @data, [ id => "queue/".$queue->Id ]; + foreach my $key (@fields) { + push @data, [ $key => $queue->$key ]; + } + + my %k = map {@$_} @data; + $o = [ map {$_->[0]} @data ]; + $k = \%k; +} +else { + my ($get, $set, $key, $val, $n, $s); + + foreach $key (keys %data) { + $val = $data{$key}; + $key = lc $key; + $n = 1; + + if (exists $fields{$key}) { + $key = $fields{$key}; + $set = "Set$key"; + + next if $val eq $queue->$key; + ($n, $s) = $queue->$set($val); + } + elsif ($key ne 'id') { + $n = 0; + $s = "Unknown field."; + } + + SET: + if ($n == 0) { + $e = 1; + push @comments, "# $key: $s"; + unless (@$o) { + my %o = keys %$changes; + delete @o{"id", @fields}; + @$o = ("id", @fields, keys %o); + $k = $changes; + } + } + } + + push(@comments, "# Queue $id updated.") unless $n == 0; +} + +DONE: +$c ||= join("\n", @comments) if @comments; +return [ $c, $o, $k, $e ]; +</%perl> diff --git a/rt/html/REST/1.0/Forms/queue/ns b/rt/html/REST/1.0/Forms/queue/ns new file mode 100644 index 000000000..360eea86b --- /dev/null +++ b/rt/html/REST/1.0/Forms/queue/ns @@ -0,0 +1,38 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/Forms/queue/ns +%# +<%ARGS> +$id +</%ARGS> +<%perl> +use RT::Queues; + +my $queues = new RT::Queues $session{CurrentUser}; +$queues->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id); +if ($queues->Count == 0) { + return (0, "No queue named $id exists."); +} +return $queues->Next->Id; +</%perl> diff --git a/rt/html/REST/1.0/Forms/ticket/attachments b/rt/html/REST/1.0/Forms/ticket/attachments new file mode 100644 index 000000000..bcb571a5a --- /dev/null +++ b/rt/html/REST/1.0/Forms/ticket/attachments @@ -0,0 +1,107 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/Forms/ticket/attachments +%# +<%ARGS> +$id +$args => undef +</%ARGS> +<%perl> +my @data; +my ($c, $o, $k, $e) = ("", [], {}, ""); +my $ticket = new RT::Ticket $session{CurrentUser}; + +$ticket->Load($id); +unless ($ticket->Id) { + return [ "# Ticket $id does not exist.", [], {}, 1 ]; +} + +my @arglist = split('/', $args); +my ($aid, $content); + +if ($arglist[1] eq 'content') { + $aid = $arglist[0]; + $content = 1; +} else { + $aid = $args; + $content = 0; +} + +if ($aid) { + unless ($aid =~ /^\d+$/) { + return [ "# Invalid attachment id: $aid", [], {}, 1 ]; + } + my $attachment = new RT::Attachment $session{CurrentUser}; + $attachment->Load($aid); + unless ($attachment->Id eq $aid) { + return [ "# Invalid attachment id: $aid", [], {}, 1 ]; + } + if ($content) { + $c = $attachment->Content; + } else { + my @data; + push @data, [ id => $attachment->Id ]; + push @data, [ Subject => $attachment->Subject ]; + push @data, [ Creator => $attachment->Creator ]; + push @data, [ Created => $attachment->Created ]; + push @data, [ Transaction => $attachment->TransactionId ]; + push @data, [ Parent => $attachment->Parent ]; + push @data, [ MessageId => $attachment->MessageId ]; + push @data, [ Filename => $attachment->Filename ]; + push @data, [ ContentType => $attachment->ContentType ]; + push @data, [ ContentEncoding => $attachment->ContentEncoding ]; + push @data, [ Headers => $attachment->Headers ]; + push @data, [ Content => $attachment->Content ]; + + my %k = map {@$_} @data; + $o = [ map {$_->[0]} @data ]; + $k = \%k; + } + +} +else { + my @attachments; + my $transactions = $ticket->Transactions; + while (my $t = $transactions->Next) { + my $attachments = $t->Attachments; + while (my $a = $attachments->Next) { + next unless $a->Filename; + my $size = length($a->Content); + if ($size > 1024) { $size = int($size/102.4)/10 . "k" } + else { $size .= "b" } + push @attachments, $a->Id.": ".$a->Filename." (".$size.")"; + } + } + + if (@attachments) { + $o = [ "id", "Attachments" ]; + $k = { + id => "ticket/".$ticket->Id."/attachments", + Attachments => \@attachments + }; + } +} + +return [ $c, $o, $k, $e ]; +</%perl> diff --git a/rt/html/REST/1.0/Forms/ticket/default b/rt/html/REST/1.0/Forms/ticket/default new file mode 100644 index 000000000..fec499b58 --- /dev/null +++ b/rt/html/REST/1.0/Forms/ticket/default @@ -0,0 +1,253 @@ +%# REST/1.0/Forms/ticket/default +%# +<%ARGS> +$id +$changes => {} +$fields => undef +</%ARGS> +<%perl> +use MIME::Entity; + +my @comments; +my ($c, $o, $k, $e) = ("", [], {}, 0); +my %data = %$changes; +my $ticket = new RT::Ticket $session{CurrentUser}; +my @dates = qw(Created Starts Started Due Resolved Told); +my @people = qw(Requestors Cc AdminCc); +my @create = qw(Queue Requestor Subject Cc AdminCc Owner Status Priority + InitialPriority FinalPriority TimeEstimated TimeWorked + TimeLeft Starts Started Due Resolved); +my @simple = qw(Subject Status Priority Disabled TimeEstimated TimeWorked + TimeLeft InitialPriority FinalPriority); +my %dates = map {lc $_ => $_} @dates; +my %people = map {lc $_ => $_} @people; +my %create = map {lc $_ => $_} @create; +my %simple = map {lc $_ => $_} @simple; + +# Are we dealing with an existing ticket? +if ($id ne 'new') { + $ticket->Load($id); + if (!$ticket->Id) { + return [ "# Ticket $id does not exist.", [], {}, 1 ]; + } + elsif (!$ticket->CurrentUserHasRight('ShowTicket') || + (%data && !$ticket->CurrentUserHasRight('ModifyTicket'))) + { + my $act = %data ? "modify" : "display"; + return [ "# You are not allowed to $act ticket $id.", [], {}, 1 ]; + } +} +else { + if (%data == 0) { + # GET ticket/new: Return a suitable default form. + # We get defaults from queue/1 (XXX: What if it isn't there?). + my $due = new RT::Date $session{CurrentUser}; + my $queue = new RT::Queue $session{CurrentUser}; + my $starts = new RT::Date $session{CurrentUser}; + $queue->Load(1); + $due->SetToNow; + $due->AddDays($queue->DefaultDueIn) if $queue->DefaultDueIn; + $starts->SetToNow; + + return [ + "# Required: Queue, Requestor, Subject", + [ qw(id Queue Requestor Subject Cc AdminCc Owner Status Priority + InitialPriority FinalPriority TimeEstimated Starts Due Text) ], + { + id => "ticket/new", + Queue => $queue->Name, + Requestor => $session{CurrentUser}->Name, + Subject => "", + Cc => [], + AdminCc => [], + Owner => "", + Status => "new", + Priority => $queue->InitialPriority, + InitialPriority => $queue->InitialPriority, + FinalPriority => $queue->FinalPriority, + TimeEstimated => 0, + Starts => $starts->ISO, + Due => $due->ISO, + Text => "", + }, + 0 + ]; + } + else { + # We'll create a new ticket, and fall through to set fields that + # can't be set in the call to Create(). + my (%v, $text); + + foreach my $k (keys %data) { + if (exists $create{lc $k}) { + $v{$create{lc $k}} = delete $data{$k}; + } + elsif (lc $k eq 'text') { + $text = delete $data{$k}; + } + } + + if ($text) { + $v{MIMEObj} = + MIME::Entity->build( + From => $session{CurrentUser}->EmailAddress, + Subject => $v{Subject}, + Data => $text + ); + } + + $ticket->Create(%v); + unless ($ticket->Id) { + return [ "# Could not create ticket.", [], {}, 1 ]; + } + + delete $data{id}; + $id = $ticket->Id; + push(@comments, "# Ticket $id created."); + goto DONE if %data == 0; + } +} + +# Now we know we're dealing with an existing ticket. +if (%data == 0) { + my ($time, $key, $val, @data); + + push @data, [ id => "ticket/".$ticket->Id ]; + push @data, [ Queue => $ticket->QueueObj->Name ] + if (!%$fields || exists $fields->{lc 'Queue'}); + push @data, [ Owner => $ticket->OwnerObj->Name ] + if (!%$fields || exists $fields->{lc 'Owner'}); + push @data, [ Creator => $ticket->CreatorObj->Name ] + if (!%$fields || exists $fields->{lc 'Creator'}); + + foreach (qw(Subject Status Priority InitialPriority FinalPriority)) { + next unless (!%$fields || (exists $fields->{lc $_})); + push @data, [$_ => $ticket->$_ ]; + } + + foreach $key (@people) { + next unless (!%$fields || (exists $fields->{lc $key})); + push @data, [ $key => [ $ticket->$key->MemberEmailAddresses ] ]; + } + + $time = new RT::Date ($session{CurrentUser}); + foreach $key (@dates) { + next unless (!%$fields || (exists $fields->{lc $key})); + $time->Set(Format => 'sql', Value => $ticket->$key); + push @data, [ $key => $time->AsString ]; + } + + $time = new RT::Date ($session{CurrentUser}); + foreach $key (qw(TimeEstimated TimeWorked TimeLeft)) { + next unless (!%$fields || (exists $fields->{lc $key})); + $val = $ticket->$key || 0; + $val = $time->DurationAsString($val*60) if $val; + push @data, [ $key => $val ]; + } + + my %k = map {@$_} @data; + $o = [ map {$_->[0]} @data ]; + $k = \%k; +} +else { + my ($get, $set, $key, $val, $n, $s); + + foreach $key (keys %data) { + $val = $data{$key}; + $key = lc $key; + $n = 1; + + if (ref $val eq 'ARRAY') { + unless ($key =~ /^(?:Requestors|Cc|AdminCc)$/i) { + $n = 0; + $s = "$key may have only one value."; + goto SET; + } + } + + if ($key =~ /^queue$/i) { + next if $val eq $ticket->QueueObj->Name; + ($n, $s) = $ticket->SetQueue($val); + } + elsif ($key =~ /^owner$/i) { + next if $val eq $ticket->OwnerObj->Name; + ($n, $s) = $ticket->SetOwner($val); + } + elsif (exists $simple{$key}) { + $key = $simple{$key}; + $set = "Set$key"; + + next if $val eq $ticket->$key; + ($n, $s) = $ticket->$set($val); + } + elsif (exists $dates{$key}) { + $key = $dates{$key}; + $set = "Set$key"; + + my $time = new RT::Date $session{CurrentUser}; + $time->Set(Format => 'sql', Value => $ticket->$key); + next if ($val =~ /^not set$/i || $val eq $time->AsString); + ($n, $s) = $ticket->$set($val); + } + elsif (exists $people{$key}) { + $key = $people{$key}; + my ($p, @msgs); + + my %new = map {$_=>1} @{ vsplit($val) }; + my %old = map {$_=>1} $ticket->$key->MemberEmailAddresses; + my $type = $key eq 'Requestors' ? 'Requestor' : $key; + + foreach $p (keys %old) { + unless (exists $new{$p}) { + ($s, $n) = $ticket->DeleteWatcher(Type => $type, + Email => $p); + push @msgs, [ $s, $n ]; + } + } + foreach $p (keys %new) { + # XXX: This is a stupid test. + unless ($p =~ /^[\w.+-]+\@([\w.-]+\.)*\w+.?$/) { + $s = 0; + $n = "$p is not a valid email address."; + push @msgs, [ $s, $n ]; + next; + } + unless ($ticket->IsWatcher(Type => $type, Email => $p)) { + ($s, $n) = $ticket->AddWatcher(Type => $type, + Email => $p); + push @msgs, [ $s, $n ]; + } + } + + $n = 1; + if (@msgs = grep {$_->[0] == 0} @msgs) { + $n = 0; + $s = join "\n", map {"# ".$_->[1]} @msgs; + $s =~ s/^# //; + } + } + elsif ($key ne 'id' && $key ne 'type') { + $n = 0; + $s = "Unknown field."; + } + + SET: + if ($n == 0) { + $e = 1; + push @comments, "# $key: $s"; + unless (@$o) { + my %o = keys %$changes; + delete $o{id}; + @$o = ("id", keys %o); + $k = $changes; + } + } + } + push(@comments, "# Ticket ".$ticket->id." updated.") unless $n == 0; +} + +DONE: +$c ||= join("\n", @comments) if @comments; +return [$c, $o, $k, $e]; + +</%perl> diff --git a/rt/html/REST/1.0/Forms/ticket/history b/rt/html/REST/1.0/Forms/ticket/history new file mode 100644 index 000000000..f5c1dc990 --- /dev/null +++ b/rt/html/REST/1.0/Forms/ticket/history @@ -0,0 +1,144 @@ +%# REST/1.0/Forms/ticket/history +%# +<%ARGS> +$id +$args => undef +$format => undef +$fields => undef +</%ARGS> +<%perl> +my $ticket = new RT::Ticket $session{CurrentUser}; +my ($c, $o, $k, $e) = ("", [], {}, ""); + +$ticket->Load($id); +unless ($ticket->Id) { + return [ "# Ticket $id does not exist.", [], {}, 1 ]; +} + +my $trans = $ticket->Transactions(); +my $total = $trans->Count(); + +chomp $args; +my @arglist = split('/', $args); +my ($type, $tid); + +if ($arglist[0] eq 'type') { + $type = $arglist[1]; +} elsif ($arglist[0] eq 'id') { + $tid = $arglist[1]; +} else { + $type = $args; +} + +if ($type) { + # Create, Set, Status, Correspond, Comment, Give, Steal, Take, Told + # CustomField, AddLink, DeleteLink, AddWatcher, DelWatcher + if ($args =~ /^links?$/) { + $trans->Limit(FIELD => 'Type', OPERATOR => 'LIKE', VALUE => '%Link'); + } + elsif ($args =~ /^watchers?$/) { + $trans->Limit(FIELD => 'Type', OPERATOR => 'LIKE', VALUE => '%Watcher'); + } + else { + $trans->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => $type); + } +} elsif ($tid) { + $trans->Limit(FIELD => 'Id', OPERATOR => '=', VALUE => $tid); +} + +if ($tid) { + my @data; + my $t = new RT::Transaction $session{CurrentUser}; + $t->Load($tid); + + push @data, [ id => $t->Id ]; + push @data, [ EffectiveTicket => $t->EffectiveTicket ] + if (!%$fields || exists $fields->{lc 'EffectiveTicket'}); + push @data, [ Ticket => $t->Ticket ] + if (!%$fields || exists $fields->{lc 'Ticket'}); + push @data, [ TimeTaken => $t->TimeTaken ] + if (!%$fields || exists $fields->{lc 'TimeTaken'}); + push @data, [ Type => $t->Type ] + if (!%$fields || exists $fields->{lc 'Type'}); + push @data, [ Field => $t->Field ] + if (!%$fields || exists $fields->{lc 'Field'}); + push @data, [ OldValue => $t->OldValue ] + if (!%$fields || exists $fields->{lc 'OldValue'}); + push @data, [ NewValue => $t->NewValue ] + if (!%$fields || exists $fields->{lc 'NewValue'}); + push @data, [ Data => $t->Data ] + if (!%$fields || exists $fields->{lc 'Data'}); + push @data, [ Description => $t->Description ] + if (!%$fields || exists $fields->{lc 'Description'}); + push @data, [ Content => $t->Content ] + if (!%$fields || exists $fields->{lc 'Content'}); + + + if (!%$fields || exists $fields->{lc 'Content'}) { + my $creator = new RT::User $session{CurrentUser}; + $creator->Load($t->Creator); + push @data, [ Creator => $creator->Name ]; + } + push @data, [ Created => $t->Created ] + if (!%$fields || exists $fields->{lc 'Created'}); + + if (!%$fields || exists $fields->{lc 'Attachments'}) { + my $attachlist; + my $attachments = $t->Attachments; + while (my $a = $attachments->Next) { + my $size = length($a->Content); + if ($size > 1024) { $size = int($size/102.4)/10 . "k" } + else { $size .= "b" } + $attachlist .= "\n" . $a->Id.": ".($a->Filename || "untitled")." (".$size.")"; + } + + push @data, [Attachments => $attachlist]; + } + + my %k = map {@$_} @data; + $o = [ map {$_->[0]} @data ]; + $k = \%k; + +} else { + my (@data, $tids); + $format ||= "s"; + $format = "l" if (%$fields); + + while (my $t = $trans->Next) { + my $tid = $t->Id; + + if ($format eq "l") { + $tids .= "," if $tids; + $tids .= $tid; + } else { + push @$o, $tid; + $k->{$tid} = $t->Description; + } + } + + if ($format eq "l") { + my @tid; + push @tid, "ticket/$id/history/id/$tids"; + my $fieldstring; + foreach my $key (keys %$fields) { + $fieldstring .= "," if $fieldstring; + $fieldstring .= $key; + } + my ($content, $forms); + + $m->subexec("$RT::WebPath/REST/1.0/show", + id => \@tid, + format => $format, + fields => $fieldstring); + return [ $c, $o, $k, $e ]; + } +} + +if (!$c) { + my $sub = $trans->Count(); + $c = "# $sub/$total ($args/total)"; +} + +return [ $c, $o, $k, $e ]; + +</%perl> diff --git a/rt/html/REST/1.0/Forms/ticket/links b/rt/html/REST/1.0/Forms/ticket/links new file mode 100644 index 000000000..8ac9dc29d --- /dev/null +++ b/rt/html/REST/1.0/Forms/ticket/links @@ -0,0 +1,148 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/Forms/ticket/links +%# +<%ARGS> +$id +$format => 's' +$changes => undef +</%ARGS> +<%perl> +my @data; +my $ticket = new RT::Ticket $session{CurrentUser}; + +$ticket->Load($id); +if (!$ticket->Id) { + return [ "# Ticket $id does not exist.", [], {}, 1 ]; +} + +my ($c, $o, $k, $e) = ("", [], {}, 0); +my @fields = qw(DependsOn DependedOnBy RefersTo ReferredToBy Members MemberOf); +my %fields = map { lc $_ => $_ } @fields; + +my %lfields = ( + Members => { Type => 'MemberOf', Mode => 'Base' }, + ReferredToBy => { Type => 'RefersTo', Mode => 'Base' }, + DependedOnBy => { Type => 'DependsOn', Mode => 'Base' }, + MemberOf => { Type => 'MemberOf', Mode => 'Target' }, + RefersTo => { Type => 'RefersTo', Mode => 'Target' }, + DependsOn => { Type => 'DependsOn', Mode => 'Target' }, +); + +if ($changes) { + my ($get, $set, $key, $val, $n, $s); + my %data = %$changes; + my @comments; + + foreach $key (keys %data) { + $val = $data{$key}; + $key = lc $key; + $n = 1; + + if (exists $fields{$key}) { + $key = $fields{$key}; + + my %old; + my $field = $lfields{$key}->{Mode}; + while (my $link = $ticket->$key->Next) { + $old{$link->$field} = 1; + } + + my %new; + foreach my $nkey (@{vsplit($val)}) { + if ($nkey =~ /^\d+$/) { + my $uri = new RT::URI $session{CurrentUser}; + my $tick = new RT::Ticket $session{CurrentUser}; + $tick->Load($nkey); + if ($tick->Id) { + $nkey = $uri->FromObject($tick); + } + else { + $n = 0; + $s = "Ticket $nkey does not exist."; + goto SET; + } + } + $new{$nkey} = 1; + } + + foreach my $u (keys %old) { + if (exists $new{$u}) { + delete $new{$u}; + } + else { + my $type = $lfields{$key}->{Type}; + my $mode = $lfields{$key}->{Mode}; + ($n, $s) = $ticket->DeleteLink(Type => $type, $mode => $u); + goto SET; + } + } + foreach my $u (keys %new) { + my $type = $lfields{$key}->{Type}; + my $mode = $lfields{$key}->{Mode}; + ($n, $s) = $ticket->AddLink(Type => $type, $mode => $u); + goto SET; + } + } + elsif ($key ne 'id' && $key ne 'type') { + $n = 0; + $s = "Unknown field: $key"; + } + + SET: + if ($n == 0) { + $e = 1; + push @comments, "# $key: $s"; + unless (@$o) { + @$o = ("id", @fields); + %$k = %data; + } + } + } + + push(@comments, "# Links for ticket $id updated.") unless @comments; + $c = join("\n", @comments) if @comments; +} +else { + my @data; + + push @data, [ id => "ticket/".$ticket->Id."/links" ]; + foreach my $key (@fields) { + my @val; + + my $field = $lfields{$key}->{Mode}; + while (my $link = $ticket->$key->Next) { + push @val, $link->$field; + } + push(@val, "") if (@val == 0 && $format eq 'l'); + push @data, [ $key => [ @val ] ] if @val; + } + + my %k = map {@$_} @data; + $o = [ map {$_->[0]} @data ]; + $k = \%k; +} + +return [ $c, $o, $k, $e ]; +</%perl> diff --git a/rt/html/REST/1.0/Forms/user/default b/rt/html/REST/1.0/Forms/user/default new file mode 100644 index 000000000..6b216e072 --- /dev/null +++ b/rt/html/REST/1.0/Forms/user/default @@ -0,0 +1,141 @@ +%# REST/1.0/Forms/user/default +%# +<%ARGS> +$id +$format => 's' +$changes => {} +</%ARGS> +<%perl> +my @comments; +my ($c, $o, $k, $e) = ("", [], {}, 0); +my %data = %$changes; +my $user = new RT::User $session{CurrentUser}; +my @fields = qw(RealName NickName Gecos Organization Address1 Address2 City + State Zip Country HomePhone WorkPhone MobilePhone PagerPhone + FreeformContactInfo Comments Signature Lang EmailEncoding + WebEncoding ExternalContactInfoId ContactInfoSystem + ExternalAuthId AuthSystem); +my %fields = map { lc $_ => $_ } @fields; + +if ($id ne 'new') { + $user->Load($id); + if (!$user->Id) { + return [ "# User $id does not exist.", [], {}, 1 ]; + } +} +else { + if (%data == 0) { + return [ + "# Required: Name, EmailAddress", + [ qw(id Name EmailAddress Organization Password Comments) ], + { + id => "user/new", + Name => "", + EmailAddress => "", + Organization => "", + Password => "", + Comments => "" + }, + 0 + ]; + } + else { + my %v; + my %create = %fields; + $create{name} = "Name"; + $create{password} = "Password"; + $create{emailaddress} = "EmailAddress"; + $create{contactinfo} = "FreeformContactInfo"; + # Do any fields need to be excluded here? + + foreach my $k (keys %data) { + if (exists $create{lc $k}) { + $v{$create{lc $k}} = delete $data{$k}; + } + } + + $user->Create(%v); + unless ($user->Id) { + return [ "# Could not create user.", [], {}, 1 ]; + } + + $id = $user->Id; + delete $data{id}; + push(@comments, "# User $id created."); + goto DONE if %data == 0; + } +} + +if (%data == 0) { + my @data; + + push @data, [ id => "user/".$user->Id ]; + push @data, [ Name => $user->Name ]; + push @data, [ Password => '********' ]; + push @data, [ EmailAddress => $user->EmailAddress ]; + + foreach my $key (@fields) { + my $val = $user->$key; + + if ($format eq 'l' || (defined $val && $val ne '')) { + $key = "ContactInfo" if $key eq 'FreeformContactInfo'; + push @data, [ $key => $val ]; + } + } + + my %k = map {@$_} @data; + $o = [ map {$_->[0]} @data ]; + $k = \%k; +} +else { + my ($get, $set, $key, $val, $n, $s); + + foreach $key (keys %data) { + $val = $data{$key}; + $key = lc $key; + $n = 1; + + if ($key eq 'name' || $key eq 'emailaddress' || + $key eq 'contactinfo' || exists $fields{$key}) + { + if (exists $fields{$key}) { + $key = $fields{$key}; + } + else { + $key = "FreeformContactInfo" if $key eq 'contactinfo'; + $key = "EmailAddress" if $key eq 'emailaddress'; + $key = "Name" if $key eq 'name'; + } + $set = "Set$key"; + + next if $val eq $user->$key; + ($n, $s) = $user->$set($val); + } + elsif ($key eq 'password') { + ($n, $s) = $user->SetPassword($val) unless $val =~ /^\**$/; + } + elsif ($key ne 'id') { + $n = 0; + $s = "Unknown field."; + } + + SET: + if ($n == 0) { + $e = 1; + push @comments, "# $key: $s"; + unless (@$o) { + my %o = keys %$changes; + delete @o{"id", @fields}; + @$o = ("id", @fields, keys %o); + $k = $changes; + } + } + } + + push(@comments, "# User $id updated.") unless $n == 0; +} + +DONE: +$c ||= join("\n", @comments) if @comments; +return [ $c, $o, $k, $e ]; +</%perl> diff --git a/rt/html/REST/1.0/Forms/user/ns b/rt/html/REST/1.0/Forms/user/ns new file mode 100644 index 000000000..36b323746 --- /dev/null +++ b/rt/html/REST/1.0/Forms/user/ns @@ -0,0 +1,41 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/Forms/user/ns +%# +<%ARGS> +$id +</%ARGS> +<%perl> +use RT::Users; + +my $field = "Name"; +$field = "EmailAddress" if $id =~ /\@/; + +my $users = new RT::Users $session{CurrentUser}; +$users->Limit(FIELD => $field, OPERATOR => '=', VALUE => $id); +if ($users->Count == 0) { + return (0, "No user named $id exists."); +} +return $users->Next->Id; +</%perl> diff --git a/rt/html/REST/1.0/NoAuth/mail-gateway b/rt/html/REST/1.0/NoAuth/mail-gateway index 8db80d5ff..359331f58 100644 --- a/rt/html/REST/1.0/NoAuth/mail-gateway +++ b/rt/html/REST/1.0/NoAuth/mail-gateway @@ -29,12 +29,15 @@ $ticket => undef </%ARGS> <%init> use RT::Interface::Email; -my ( $status, $error, $Ticket ) = RT::Interface::Email::Gateway( %ARGS); +my ( $status, $error, $Ticket ) = RT::Interface::Email::Gateway(\%ARGS); </%init> <%flags> inherit => undef # inhibit UTF8 conversion done in /autohandler </%flags> -% if ($status) { +% if ($status == -75 ) { +temporary failure +% } +% elsif ($status == 1) { ok % if ( $Ticket->Id ) { Ticket: <% $Ticket->Id %> diff --git a/rt/html/REST/1.0/autohandler b/rt/html/REST/1.0/autohandler new file mode 100644 index 000000000..9084a1bef --- /dev/null +++ b/rt/html/REST/1.0/autohandler @@ -0,0 +1,32 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/autohandler +%# +<%INIT> +use RT::Interface::REST; +$r->content_type('text/plain'); +$m->error_format('text'); +$m->call_next(); +$m->abort(); +</%INIT> diff --git a/rt/html/REST/1.0/dhandler b/rt/html/REST/1.0/dhandler new file mode 100644 index 000000000..ef5217fe0 --- /dev/null +++ b/rt/html/REST/1.0/dhandler @@ -0,0 +1,287 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/dhandler +%# +<%ARGS> +@id => () +$fields => undef +$format => undef +$content => undef +</%ARGS> +<%INIT> +use RT::Interface::REST; + +my $output = ""; +my $status = "200 Ok"; +my $object = $m->dhandler_arg; + +my $name = qr{[\w.-]+}; +my $list = '(?:(?:\d+-)?\d+,)*(?:\d+-)?\d+'; +my $label = '[a-zA-Z0-9@_.+-]+'; +my $field = '[a-zA-Z][a-zA-Z0-9_-]*'; +my $labels = "(?:$label,)*$label"; + +# We must handle requests such as the following: +# +# 1. http://.../REST/1.0/show (with a list of object specifications). +# 2. http://.../REST/1.0/edit (with a self-contained list of forms). +# 3. http://.../REST/1.0/ticket/show (implicit type specification). +# http://.../REST/1.0/ticket/edit +# 4. http://.../REST/1.0/ticket/nn (all possibly with a single form). +# http://.../REST/1.0/ticket/nn/history +# http://.../REST/1.0/ticket/nn/attachment/1 +# +# Objects are specified by their type, and either a unique numeric ID, +# or a unique name (e.g. ticket/1, queue/foo). Multiple objects of the +# same type may be specified by a comma-separated list of identifiers +# (e.g., user/ams,rai or ticket/1-3,5-7). +# +# Ultimately, we want a list of object specifications to operate upon. +# The URLs in (4) provide enough information to identify an object. We +# will assemble submitted information into that format in other cases. +# +my (@objects, $forms); +my $utype; + +if ($object eq 'show' || # $REST/show + (($utype) = ($object =~ m{^($name)/show$}))) # $REST/ticket/show +{ + # We'll convert type/range specifications ("ticket/1-3,7-9/history") + # into a list of singular object specifications ("ticket/1/history"). + # If the URL specifies a type, we'll accept only that one. + foreach my $id (@id) { + $id =~ s|^(?:$utype/)?|$utype/| if $utype; + if (my ($type, $oids, $extra) = + ($id =~ m#^($name)/($list|$labels)(?:(/.*))?$#o)) + { + foreach my $oid (expand_list($oids)) { + if ($extra =~ m{^(?:/($name)(?:/(.*))?)?$}o) { + my ($attr, $args) = ($1, $2); + # expand transaction and attachment range specifications + # (if applicable) + my $tids; + if ($attr eq 'history' && $args =~ m#id/(\d.*)#o) { + $tids = $1; + } + if ($tids) { + push(@objects, "$type/$oid/$attr/id/$_") for expand_list($tids); + } else { + push(@objects, "$type/$oid$extra"); + } + } + } + } + else { + $status = "400 Bad Request"; + $output = "Invalid object ID specified: '$id'"; + goto OUTPUT; + } + } +} +elsif ($object eq 'edit' || # $REST/edit + (($utype) = ($object =~ m{^($name)/edit$}))) # $REST/ticket/edit +{ + # We'll make sure each of the submitted forms is syntactically valid + # and sufficiently identifies an object to operate upon, then add to + # the object list as above. + my @output; + + $forms = form_parse($content); + foreach my $form (@$forms) { + my ($c, $o, $k, $e) = @$form; + + if ($e) { + push @output, [ "# Syntax error.", $o, $k, $e ]; + } + else { + my ($type, $id); + + # Look for matching types in the ID, form, and URL. + $type = exists $k->{type} ? $k->{type} : $utype; + $type =~ s|^(?:$utype)?|$utype/| if $utype; + $type =~ s|/$||; + + if (exists $k->{id}) { + $id = $k->{id}; + $id =~ s|^(?:$type/)?|$type/| if $type; + + if ($id =~ m#^$name/(?:$label|\d+)(?:/.*)?#o) { + push @objects, $id; + } + else { + push @output, [ "# Invalid object ID: '$id'", $o, $k, $e ]; + } + } + else { + push @output, [ "# No object ID specified.", $o, $k, $e ]; + } + } + } + # If we saw any errors at this stage, we won't process any part of + # the submitted data. + if (@output) { + unshift @output, [ "# Please resubmit with errors corrected." ]; + $status = "409 Syntax Error"; + $output = form_compose(\@output); + goto OUTPUT; + } +} +else { + # We'll assume that this is in the correct format already. Otherwise + # it will be caught by the loop below. + push @objects, $object; + + if ($content) { + $forms = form_parse($content); + + if (@$forms > 1) { + $status = "400 Bad Request"; + $output = "You may submit only one form to this object."; + goto OUTPUT; + } + + my ($c, $o, $k, $e) = @{ $forms->[0] }; + if ($e) { + $status = "409 Syntax Error"; + $output = form_compose([ ["# Syntax error.", $o, $k, $e] ]); + goto OUTPUT; + } + } +} + +# Make sure we have something to do. +unless (@objects) { + $status = "400 Bad Request"; + $output = "No objects specified."; + goto OUTPUT; +} + +# Parse and validate any field specifications. +my (%fields, @fields); +if ($fields) { + unless ($fields =~ /^(?:$field,)*$field$/) { + $status = "400 Bad Request"; + $output = "Invalid field specification: $fields"; + goto OUTPUT; + } + @fields = map lc, split /,/, $fields; + @fields{@fields} = (); + unless (exists $fields{id}) { + unshift @fields, "id"; + $fields{id} = (); + } +} + +my (@comments, @output); + +foreach $object (@objects) { + my ($handler, $type, $id, $attr, $args); + my ($c, $o, $k, $e) = ("", ["id"], {id => $object}, 0); + + my $i = 0; + if ($object =~ m{^($name)/(\d+|$label)(?:/($name)(?:/(.*))?)?$}o || + $object =~ m{^($name)/(new)$}o) + { + ($type, $id, $attr, $args) = ($1, $2, ($3 || 'default'), $4); + $handler = "Forms/$type/$attr"; + + unless ($m->comp_exists($handler)) { + $args = "$attr/$args"; + $handler = "Forms/$type/default"; + + unless ($m->comp_exists($handler)) { + $i = 2; + $c = "# Unknown object type: $type"; + } + } + elsif ($id ne 'new' && $id !~ /^\d+$/) { + my $ns = "Forms/$type/ns"; + + # Can we resolve named objects? + unless ($m->comp_exists($ns)) { + $i = 3; + $c = "# Objects of type $type must be specified by numeric id."; + } + else { + my ($n, $s) = $m->comp("Forms/$type/ns", id => $id); + if ($n <= 0) { $i = 4; $c = "# $s"; } + else { $i = 0; $id = $n; } + } + } + else { + $i = 0; + } + } + else { + $i = 1; + $c = "# Invalid object specification: '$object'"; + } + + if ($i != 0) { + if ($content) { + (undef, $o, $k, $e) = @{ shift @$forms }; + } + push @output, [ $c, $o, $k ]; + next; + } + + unless ($content) { + my $d = $m->comp($handler, id => $id, args => $args, format => $format, fields => \%fields); + my ($c, $o, $k, $e) = @$d; + + if (!$e && @$o && keys %fields) { + my %lk = map { lc $_ => $_ } keys %$k; + @$o = map { $lk{$_} } @fields; + foreach my $key (keys %$k) { + delete $k->{$key} unless exists $fields{lc $key}; + } + } + push(@output, [ $c, $o, $k ]) if ($c || @$o || keys %$k); + } + else { + my ($c, $o, $k, $e) = @{ shift @$forms }; + my $d = $m->comp($handler, id => $id, args => $args, format => $format, + changes => $k); + ($c, $o, $k, $e) = @$d; + + # We won't pass $e through to compose, trusting instead that the + # handler added suitable comments for the user. + if ($e) { + $status = "409 Syntax Error" if @$o; + push @output, [ $c, $o, $k ]; + } + else { + push @comments, $c; + } + } +} + +unshift(@output, [ join "\n", @comments ]) if @comments; +$output = form_compose(\@output); + +OUTPUT: +</%INIT> +RT/<% $RT::VERSION %> <% $status %> + +<% $output |n %> diff --git a/rt/html/REST/1.0/logout b/rt/html/REST/1.0/logout new file mode 100644 index 000000000..b64938bc2 --- /dev/null +++ b/rt/html/REST/1.0/logout @@ -0,0 +1,27 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +<%PERL> +tied(%session)->delete if (defined %session); +</%PERL> +RT/<% $RT::VERSION %> 200 Ok diff --git a/rt/html/REST/1.0/search/dhandler b/rt/html/REST/1.0/search/dhandler new file mode 100644 index 000000000..90b4653e5 --- /dev/null +++ b/rt/html/REST/1.0/search/dhandler @@ -0,0 +1,32 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/search/dhandler +%# +<%INIT> +my $status = "500 Server Error"; +my $output = "Unsupported object type."; +</%INIT> +RT/<% $RT::VERSION %> <% $status %> + +<% $output |n %> diff --git a/rt/html/REST/1.0/search/ticket b/rt/html/REST/1.0/search/ticket new file mode 100644 index 000000000..24435294e --- /dev/null +++ b/rt/html/REST/1.0/search/ticket @@ -0,0 +1,119 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/search/ticket +%# +<%ARGS> +$query +$format => undef +$orderby => undef +$fields => undef +</%ARGS> +<%INIT> +my $output = ""; +my $status = "200 Ok"; +my $tickets = new RT::Tickets $session{CurrentUser}; + +# Parse and validate any field specifications. +my $field = '[a-zA-Z][a-zA-Z0-9_-]*'; +my (%fields, @fields); +if ($fields) { + $format = "l"; + unless ($fields =~ /^(?:$field,)*$field$/) { + $status = "400 Bad Request"; + $output = "Invalid field specification: $fields"; + goto OUTPUT; + } + @fields = map lc, split /,/, $fields; + @fields{@fields} = (); + unless (exists $fields{id}) { + unshift @fields, "id"; + $fields{id} = (); + } +} + +$format ||= "s"; +if ($format !~ /^[isl]$/) { + $status = "400 Bad request"; + $output = "Unknown listing format: $format. (Use i, s, or l.)\n"; + goto OUTPUT; +} + +my ($n, $s); +eval { + ($n, $s) = $tickets->FromSQL($query); +}; +my $sortstring = ""; +if ($orderby) { + $sortstring = 'FIELD => '; + my $order = substr($orderby, 0, 1); + if ($order eq '+' || $order eq '-') { + $sortstring .= 'substr($orderby, 1)'; + if ($order eq '+') { + $sortstring .= ", ORDER => 'ASC'"; + } elsif ($order eq '-') { + $sortstring .= ", ORDER => 'DESC'"; + } + } else { + $sortstring .= '$orderby'; + } + my $foo = 'FIELD => '; + $foo .= '$orderby'; + $tickets->OrderBy(eval $sortstring); +} +if ($@ || $n == 0) { + $s ||= $@; + $status = "400 Bad request"; + $output = "Invalid query: '$s'.\n"; + goto OUTPUT; +} + +$n = 0; +my @output; +while (my $ticket = $tickets->Next) { + $n++; + + if ($format eq "i") { + $output .= "ticket/" . $ticket->Id . "\n"; + } + elsif ($format eq "s") { + $output .= $ticket->Id . ": ". $ticket->Subject . "\n"; + } + else { + my $id = $ticket->Id; + my $d = $m->comp("$RT::WebPath/REST/1.0/Forms/ticket/default", id => $id, format => $format, fields => \%fields); + my ($c, $o, $k, $e) = @$d; + push @output, [ $c, $o, $k ]; + } +} +if ($n == 0 && $format ne "i") { + $output = "No matching results.\n"; +} + +$output = form_compose(\@output) if @output; + +OUTPUT: +</%INIT> +RT/<% $RT::VERSION %> <% $status %> + +<% $output |n %> diff --git a/rt/html/REST/1.0/ticket/comment b/rt/html/REST/1.0/ticket/comment new file mode 100644 index 000000000..9d1b06246 --- /dev/null +++ b/rt/html/REST/1.0/ticket/comment @@ -0,0 +1,149 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/ticket/comment +%# +<%ARGS> +$content +</%ARGS> +<%INIT> +use MIME::Entity; +use LWP::MediaTypes; +use RT::Interface::REST; +use File::Temp qw(tempfile); + +my $ticket = new RT::Ticket $session{CurrentUser}; +my $object = $r->path_info; +my $status = "200 Ok"; +my $output; +my $action; + +# http://.../REST/1.0/ticket/comment/1 +my ($c, $o, $k, $e) = @{ form_parse($content)->[0] }; +if ($e || !$o) { + if (!$o) { + $output = "Empty form submitted.\n"; + } + else { + $c = "# Syntax error."; + $output = form_compose([[$c, $o, $k, $e]]); + } + $status = "400 Bad Request"; + goto OUTPUT; +} + +$object =~ s#^/##; +$object ||= $k->{Ticket}; +unless ($object =~ /^\d+/) { + $output = "Invalid ticket id: `$object'.\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} +if ($k->{Ticket} && $object ne $k->{Ticket}) { + $output = "The submitted form and URL specify different tickets.\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} + +($action = $k->{Action}) =~ s/^(.)(.*)$/\U$1\L$2\E/; +unless ($action =~ /^(?:Comment|Correspond)$/) { + $output = "Invalid action: `$action'.\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} + +my $text = $k->{Text}; +my @atts = @{ vsplit($k->{Attachment}) }; + +if (!$k->{Text} && @atts == 0) { + $status = "400 Bad Request"; + $output = "Empty comment with no attachments submitted.\n"; + goto OUTPUT; +} + +my $cgi = $m->cgi_object; +my $ent = MIME::Entity->build(Type => "multipart/mixed"); +$ent->attach(Data => $k->{Text}) if $k->{Text}; + +my $i = 1; +foreach my $att (@atts) { + local $/=undef; + my $file = $att; + $file =~ s#^.*[\\/]##; + + my $fh = $cgi->upload("attachment_$i"); + if ($fh) { + my $buf; + my ($w, $tmp) = tempfile(); + my $info = $cgi->uploadInfo(); + + while (sysread($fh, $buf, 8192)) { + syswrite($w, $buf); + } + + $ent->attach( + Path => $tmp, + Type => $info->{'Content-Type'} || guess_media_type($tmp), + Filename => $file, + Disposition => "attachment" + ); + } + else { + $status = "400 Bad Request"; + $output = "No attachment for $att.\n"; + goto OUTPUT; + } + + $i++; +} + +$ticket->Load($object); +unless ($ticket->Id) { + $output = "Couldn't load ticket id: `$object'.\n"; + $status = "404 Ticket not found"; + goto OUTPUT; +} +unless ($ticket->CurrentUserHasRight('ModifyTicket') || + ($action eq "Comment" && + $ticket->CurrentUserHasRight("CommentOnTicket")) || + ($action eq "Correspond" && + $ticket->CurrentUserHasRight("ReplyToTicket"))) +{ + $output = "You are not allowed to $action on ticket $object.\n"; + $status = "403 Permission denied"; + goto OUTPUT; +} + +my $cc = join ", ", @{ vsplit($k->{Cc}) }; +my $bcc = join ", ", @{ vsplit($k->{Bcc}) }; +my ($n, $s) = $ticket->$action(MIMEObj => $ent, + CcMessageTo => $cc, + BccMessageTo => $bcc, + TimeTaken => $k->{TimeWorked} || 0); +$output = $s; + +OUTPUT: +</%INIT> +RT/<% $RT::VERSION %> <% $status %> + +<% $output |n %> diff --git a/rt/html/REST/1.0/ticket/link b/rt/html/REST/1.0/ticket/link new file mode 100644 index 000000000..574762512 --- /dev/null +++ b/rt/html/REST/1.0/ticket/link @@ -0,0 +1,96 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/ticket/link +%# +<%ARGS> +$id => undef +$del => 0 +$rel +$to +</%ARGS> +<%INIT> +use RT::Interface::REST; + +my $output; +my $status = "200 Ok"; +my $ticket = new RT::Ticket $session{CurrentUser}; +my $object = $r->path_info; + +my @fields = qw(DependsOn DependedOnBy RefersTo ReferredToBy HasMember MemberOf); +my %fields = map { lc $_ => $_ } @fields; +my %lfields = ( + HasMember => { Type => 'MemberOf', Mode => 'Base' }, + ReferredToBy => { Type => 'RefersTo', Mode => 'Base' }, + DependedOnBy => { Type => 'DependsOn', Mode => 'Base' }, + MemberOf => { Type => 'MemberOf', Mode => 'Target' }, + RefersTo => { Type => 'RefersTo', Mode => 'Target' }, + DependsOn => { Type => 'DependsOn', Mode => 'Target' }, +); + +# http://.../REST/1.0/ticket/link/1 + +$object =~ s#^/##; +if ($id && $object && $id != $object) { + $output = "Different ids in URL (`$object') and submitted form (`$id').\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} +$id ||= $object; +unless ($id =~ /^\d+$/ && $to =~ /^\d+$/) { + my $bad = ($id !~ /^\d+$/) ? $id : $to; + $output = $r->path_info. "\n"; + $output .= "Invalid ticket id: '$bad'.\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} +unless (exists $fields{lc $rel}) { + $output = "Invalid relationship: '$rel'.\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} +$rel = $fields{lc $rel}; + +$ticket->Load($id); +unless ($ticket->Id) { + $output = "Couldn't load ticket id: '$id'.\n"; + $status = "404 Ticket not found"; + goto OUTPUT; +} + +my $type = $lfields{$rel}->{Type}; +my $mode = $lfields{$rel}->{Mode}; + +my $n = 1; +my $op = $del ? "DeleteLink" : "AddLink"; + +($n, $output) = $ticket->$op(Type => $type, $mode => $to); +if ($n == 0) { + $status = "500 Error"; +} + +OUTPUT: +</%INIT> +RT/<% $RT::VERSION %> <% $status %> + +<% $output |n %> diff --git a/rt/html/REST/1.0/ticket/merge b/rt/html/REST/1.0/ticket/merge new file mode 100644 index 000000000..9cd2a7cfa --- /dev/null +++ b/rt/html/REST/1.0/ticket/merge @@ -0,0 +1,78 @@ +%# BEGIN LICENSE BLOCK +%# +%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +%# +%# (Except where explictly superceded by other copyright notices) +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# Unless otherwise specified, all modifications, corrections or +%# extensions to this work which alter its source code become the +%# property of Best Practical Solutions, LLC when submitted for +%# inclusion in the work. +%# +%# +%# END LICENSE BLOCK +%# REST/1.0/ticket/merge +%# +<%ARGS> +$id => undef +$into +</%ARGS> +<%INIT> +use RT::Interface::REST; + +my $output; +my $status = "200 Ok"; +my $ticket = new RT::Ticket $session{CurrentUser}; +my $object = $r->path_info; + +# http://.../REST/1.0/ticket/merge/1 + +$object =~ s#^/##; +if ($id && $object && $id != $object) { + $output = "Different ids in URL (`$object') and submitted form (`$id').\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} +$id ||= $object; +unless ($id =~ /^\d+$/ && $into =~ /^\d+$/) { + my $bad = ($id !~ /^\d+$/) ? $id : $into; + $output = $r->path_info. "\n"; + $output .= "Invalid ticket id: `$bad'.\n"; + $status = "400 Bad Request"; + goto OUTPUT; +} + +$ticket->Load($id); +unless ($ticket->Id) { + $output = "Couldn't load ticket id: `$id'.\n"; + $status = "404 Ticket not found"; + goto OUTPUT; +} +unless ($ticket->CurrentUserHasRight('ModifyTicket')) { + $output = "You are not allowed to modify ticket $id.\n"; + $status = "403 Permission denied"; + goto OUTPUT; +} + +my ($n, $s) = $ticket->MergeInto($into); + +if ($n == 0) { + $status = "500 Error"; +} +$output = $s; + +OUTPUT: +</%INIT> +RT/<% $RT::VERSION %> <% $status %> + +<% $output |n %> diff --git a/rt/html/Search/Bulk.html b/rt/html/Search/Bulk.html index df43cfa50..de9143c8a 100644 --- a/rt/html/Search/Bulk.html +++ b/rt/html/Search/Bulk.html @@ -175,6 +175,7 @@ if ($ARGS{'UpdateContent'} && #Iterate through each ticket we've been handed my @linkresults; +$session{'tickets'}->RedoSearch(); while (my $Ticket = $session{'tickets'}->Next) { $RT::Logger->debug( "Checking Ticket ".$Ticket->Id ."\n"); next unless ($ARGS{"UpdateTicket".$Ticket->Id}); diff --git a/rt/html/Search/Elements/PickRestriction b/rt/html/Search/Elements/PickRestriction index a6911df5a..0021ab2bc 100644 --- a/rt/html/Search/Elements/PickRestriction +++ b/rt/html/Search/Elements/PickRestriction @@ -34,9 +34,10 @@ <& /Elements/SelectOwner, Name => "ValueOfOwner" &> <li> -<&|/l&>Requestor email address</&> -<& /Elements/SelectMatch, Name => "RequestorOp" &> -<INPUT Name="ValueOfRequestor" SIZE=20> +<& /Elements/SelectWatcherType, Name => "WatcherRole", AllowNull => 0 &> +<&|/l&>email address</&> +<& /Elements/SelectMatch, Name => "WatcherRoleOp" &> +<INPUT Name="ValueOfWatcherRole" SIZE=20> <li> <&|/l&>Subject</&> <& /Elements/SelectMatch, Name => "SubjectOp" &> @@ -47,7 +48,7 @@ False => loc("isn't"), TrueVal=> '=', FalseVal => '!=' &> -<& /Elements/SelectQueue, Name => loc("ValueOfQueue") &> +<& /Elements/SelectQueue, Name => "ValueOfQueue" &> <li><&|/l&>Priority</&> <& /Elements/SelectEqualityOperator, Name => "PriorityOp" &> @@ -77,7 +78,7 @@ TrueVal=> '=', FalseVal => '!=' &> -<& /Elements/SelectStatus, Name => "ValueOfStatus" &> +<& /Elements/SelectStatus, Name => "ValueOfStatus", SkipDeleted => 1 &> % while ( my $CustomField = $CustomFields->Next ) { diff --git a/rt/html/SelfService/Display.html b/rt/html/SelfService/Display.html index fc3fcb289..124ecf407 100644 --- a/rt/html/SelfService/Display.html +++ b/rt/html/SelfService/Display.html @@ -38,7 +38,7 @@ <& /Elements/TitleBoxStart, title => loc("Dates"), title_class=> 'inverse', color => "#663366" &> - <& /Ticket/Elements/ShowDates, Ticket => $Ticket &> + <& /Ticket/Elements/ShowDates, Ticket => $Ticket, UpdatedLink => 0 &> <& /Elements/TitleBoxEnd &> </TD> </TR> @@ -46,7 +46,7 @@ -<& /Ticket/Elements/ShowHistory, Ticket => $Ticket&> +<& /Ticket/Elements/ShowHistory, Ticket => $Ticket, AttachPath => "Attachment" &> @@ -101,6 +101,12 @@ if ( $id[0] eq 'new' ) { push ( @results, $ErrMsg ); # }}} + +# delete temporary storage entry to make WebUI clean +unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) { + delete $session{'Attachments'}; +} +# }}} } else { unless ( $Ticket->Load( $id[0] ) ) { @@ -127,10 +133,43 @@ if ( ( defined $ARGS{'Status'} ) push @results, "$msg"; } +# {{{ store the uploaded attachment in session +if ($ARGS{'Attach'}) { # attachment? + $session{'Attachments'} = {} unless defined $session{'Attachments'}; + + my $subject = "$ARGS{'Attach'}"; + # since CGI.pm deutf8izes the magic field, we need to add it back. + Encode::_utf8_on($subject); + # strip leading directories + $subject =~ s#^.*[\\/]##; + + my $attachment = MakeMIMEEntity( + Subject => $subject, + Body => "", + AttachmentFieldName => 'Attach' + ); + + $session{'Attachments'} = { %{$session{'Attachments'} || {}}, + $ARGS{'Attach'} => $attachment }; +} +# }}} + +if ( $session{'Attachments'} || + ( $ARGS{'UpdateContent'} ne '' + && $ARGS{'UpdateContent'} ne "-- \n" + . $session{'CurrentUser'}->UserObj->Signature )) { + $ARGS{UpdateAttachments} = $session{'Attachments'}; +} ProcessUpdateMessage( ARGSRef => \%ARGS, Actions => \@results, TicketObj => $Ticket ); +# delete temporary storage entry to make WebUI clean +unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) { + delete $session{'Attachments'}; +} +# }}} + my $Transactions = $Ticket->Transactions; </%INIT> diff --git a/rt/html/SelfService/Elements/MyRequests b/rt/html/SelfService/Elements/MyRequests index 95ede0811..839359aed 100644 --- a/rt/html/SelfService/Elements/MyRequests +++ b/rt/html/SelfService/Elements/MyRequests @@ -49,6 +49,7 @@ $title ||= loc("My [_1] tickets", $friendly_status); my $MyTickets; $MyTickets = new RT::Tickets ($session{'CurrentUser'}); $MyTickets->LimitWatcher(TYPE => 'Requestor', VALUE => $session{'CurrentUser'}->EmailAddress); +$MyTickets->OrderBy(FIELD => 'id', ORDER => 'ASC'); foreach my $status (@status) { diff --git a/rt/html/SelfService/Update.html b/rt/html/SelfService/Update.html index 9ff31775f..9444aa706 100644 --- a/rt/html/SelfService/Update.html +++ b/rt/html/SelfService/Update.html @@ -29,7 +29,24 @@ <&|/l&>Status</&>: <& /Elements/SelectStatus, Name=>"Status", Default => $DefaultStatus &><br> <&|/l&>Subject</&>: <input name="UpdateSubject" size=60 value="Re: <% $Ticket->Subject %>"> <br> -<&|/l&>Attach</&>: <input name="UpdateAttachment" type=file><br> +<table> +<tr> +% if (exists $session{'Attachments'}) { +<TD> +<&|/l&>Attached file</&>: +</TD> +<TD COLSPAN=5> +<&|/l&>Check box to delete</&><BR> +% foreach my $attach_name (keys %{$session{'Attachments'}}) { +<input type="checkbox" name="DeleteAttach-<%$attach_name%>"><%$attach_name%><BR> +% } # end of foreach +</TD> +</TR> +<TR> +% } # end of if +<tr><td align=right><&|/l&>Attach</&>:</td><td><input name="Attach" type="file"><input type="hidden" name="UpdateAttach" value="1"> +</td></tr> +</table> <& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &> <INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>"><br> diff --git a/rt/html/Ticket/Attachment/dhandler b/rt/html/Ticket/Attachment/dhandler index e0f00f57a..ba82b5f2e 100644 --- a/rt/html/Ticket/Attachment/dhandler +++ b/rt/html/Ticket/Attachment/dhandler @@ -65,4 +65,6 @@ $m->out($AttachmentObj->OriginalContent); $m->abort; </%perl> - +<%attr> +AutoFlush => 0 +</%attr> diff --git a/rt/html/Ticket/Create.html b/rt/html/Ticket/Create.html index 5b8c908a1..435447a8f 100644 --- a/rt/html/Ticket/Create.html +++ b/rt/html/Ticket/Create.html @@ -34,55 +34,55 @@ <BR> <& /Elements/TitleBoxStart, contentbg => "#cccccc", title => loc("Create a new ticket") &> <TABLE border=0 cellpadding=0 cellspacing=0> -<TR><TD><&|/l&>Queue</&></TD> -<TD><% $QueueObj->Name %> +<TR><TD class=label><&|/l&>Queue</&>:</TD> +<TD class=value><% $QueueObj->Name %> <INPUT TYPE=HIDDEN NAME=Queue Value="<%$QueueObj->Name%>"> </TD> -<TD><&|/l&>Status</&>: +<TD class=label><&|/l&>Status</&>: </TD> -<TD> +<TD class=value> <& /Elements/SelectStatus, Name => "Status", Default => $ARGS{Status}||'new' &> </TD> -<TD> +<TD class=label> <&|/l&>Owner</&>: </TD> -<TD> +<TD class=value> <& /Elements/SelectOwner, Name => "Owner", QueueObj => $QueueObj, Default => $ARGS{Owner}||undef &> </TD> </TR> <TR> -<TD> +<TD class=label> <&|/l&>Requestors</&>: </TD> -<TD COLSPAN=5> +<TD class=value COLSPAN=5> <INPUT Name="Requestors" Value="<% ($ARGS{Requestors}) || $session{CurrentUser}->EmailAddress %>" SIZE=40> </TD> </TR> <TR> -<TD> +<TD class=labeltop> <&|/l&>Cc</&>: </TD> -<TD COLSPAN=5> -<INPUT NAME="Cc" SIZE=40<% $ARGS{Cc} && " VALUE=\"$ARGS{Cc}\""%>><BR> +<TD class=value COLSPAN=5> +<INPUT NAME="Cc" SIZE=40 VALUE="<% $ARGS{Cc} %>"><BR> <i><font size=-2> <&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)</&></font></i> </TD> </TR> <TR> -<TD> +<TD class=labeltop> <&|/l&>Admin Cc</&>: </TD> -<TD COLSPAN=5> -<INPUT NAME="AdminCc" SIZE=40<% $ARGS{AdminCc} && " VALUE=\"$ARGS{AdminCc}\""%>><BR> +<TD class=value COLSPAN=5> +<INPUT NAME="AdminCc" SIZE=40 VALUE="<% $ARGS{AdminCc} %>"><BR> <i><font size=-2> <&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)</&></font></i> </TD> </TR> <TR> -<TD> +<TD class=label> <&|/l&>Subject</&>: </TD> -<TD COLSPAN=5> +<TD class=value COLSPAN=5> <INPUT Name="Subject" SIZE=60 MAXSIZE=100 value="<%$ARGS{Subject} || ''%>"> </TD> </TR> @@ -93,7 +93,7 @@ </TR> <TR> % if (exists $session{'Attachments'}) { -<TD> +<TD class=label> <&|/l&>Attached file</&>: </TD> <TD COLSPAN=5> @@ -108,7 +108,7 @@ <TD> <&|/l&>Attach file</&>: </TD> -<TD COLSPAN=5> +<TD class=value COLSPAN=5> <INPUT TYPE=FILE NAME="Attach"> <INPUT TYPE=SUBMIT NAME="AddMoreAttach" VALUE="<&|/l&>Add More Files</&>"> </TD> @@ -152,8 +152,8 @@ <TABLE BORDER=0> <TR><TD ALIGN=RIGHT><&|/l&>Priority</&>:</TD><TD><input size=3 name="InitialPriority" value="<% $ARGS{InitialPriority} ? $ARGS{InitialPriority} : $QueueObj->InitialPriority %>"></TD></TR> <TR><TD ALIGN=RIGHT><&|/l&>Final Priority</&>:</TD><TD><input size=3 name="FinalPriority" value="<% $ARGS{FinalPriority} ? $ARGS{FinalPriority} : $QueueObj->FinalPriority %>"></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Time Worked</&>:</TD><TD><input size=3 name="TimeWorked"<% $ARGS{TimeWorked} && " VALUE=\"$ARGS{TimeWorked}\"" %>></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Time Left</&>:</TD><TD><input size=3 name="TimeLeft"<% $ARGS{TimeLeft} && " VALUE=\"$ARGS{TimeLeft}\"" %>></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Time Worked</&>:</TD><TD><input size=3 name="TimeWorked" value="<% $ARGS{TimeWorked} %>"></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Time Left</&>:</TD><TD><input size=3 name="TimeLeft" value="<% $ARGS{TimeLeft} %>"></TD></TR> </TABLE> <& /Elements/TitleBoxEnd &> <br> @@ -162,8 +162,9 @@ color => "#663366" &> <TABLE BORDER=0> -<TR><TD ALIGN=RIGHT><&|/l&>Starts</&>:</TD><TD><input size=10 name="Starts"<% $ARGS{Starts} && " VALUE=\"$ARGS{Starts}\"" %>></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Due</&>:</TD><TD><input size=10 name="Due"<% $ARGS{Due} && " VALUE=\"$ARGS{Due}\"" %>></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Starts</&>:</TD><TD><input size=10 name="Starts" value="<% $ARGS{Starts} %>"></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Due</&>:</TD><TD><input size=10 name="Due" value="<% +$ARGS{Due}%>"></TD></TR> </TABLE> <& /Elements/TitleBoxEnd &> <BR> @@ -176,12 +177,12 @@ <i><&|/l&>(Enter ticket ids or URLs, seperated with spaces)</&></i> <TABLE BORDER=0> -<TR><TD ALIGN=RIGHT><&|/l&>Depends on</&></TD><TD><input size=10 name="new-DependsOn"<% $ARGS{'new-DependsOn'} && " VALUE=\"$ARGS{'new-DependsOn'}\""%>></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Depended on by</&></TD><TD><input size=10 name="DependsOn-new"<% $ARGS{'DependsOn-new'} && " VALUE=\"$ARGS{'DependsOn-new'}\"" %>></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Parents</&></TD><TD><input size=10 name="new-MemberOf"<% $ARGS{'new-MemberOf'} && " VALUE=\"$ARGS{'new-MemberOf'}\"" %>></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Children</&></TD><TD><input size=10 name="MemberOf-new" <% $ARGS{'MemberOf-new'} && " VALUE=\"$ARGS{'MemberOf-new'}\"" %>></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Refers to</&></TD><TD><input size=10 name="new-RefersTo"<% $ARGS{'new-RefersTo'} && " VALUE=\"$ARGS{'new-MemberOf'}\"" %>></TD></TR> -<TR><TD ALIGN=RIGHT><&|/l&>Referred to by</&></TD><TD><input size=10 name="RefersTo-new"<% $ARGS{'RefersTo-new'} && " VALUE=\"$ARGS{'RefersTo-new'}\"" %>></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Depends on</&></TD><TD><input size=10 name="new-DependsOn" value="<% $ARGS{'new-DependsOn'} %>"></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Depended on by</&></TD><TD><input size=10 name="DependsOn-new" value="<% $ARGS{'DependsOn-new'} %>"></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Parents</&></TD><TD><input size=10 name="new-MemberOf" value="<% $ARGS{'new-MemberOf'} %>"></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Children</&></TD><TD><input size=10 name="MemberOf-new" value="<% $ARGS{'MemberOf-new'} %>"></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Refers to</&></TD><TD><input size=10 name="new-RefersTo" value="<% $ARGS{'new-RefersTo'} %>"></TD></TR> +<TR><TD ALIGN=RIGHT><&|/l&>Referred to by</&></TD><TD><input size=10 name="RefersTo-new" value="<% $ARGS{'RefersTo-new'} %>"></TD></TR> </TABLE> @@ -200,10 +201,20 @@ <BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR> <%INIT> + + + my $QueueObj = new RT::Queue($session{'CurrentUser'}); $QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded.")); my $CFs = $QueueObj->CustomFields(); +if ($QueueObj->DefaultDueIn) { + my $default_due = RT::Date->new($session{'CurrentUser'}); + $default_due->SetToNow(); + $default_due->AddDays($QueueObj->DefaultDueIn); + $ARGS{'Due'} = $default_due->ISO(); +} + # {{{ deal with deleting uploaded attachments foreach my $key (keys %ARGS) { if ($key =~ m/^DeleteAttach-(.+)$/) { @@ -218,8 +229,6 @@ if ($ARGS{'Attach'}) { # attachment? my $subject = "$ARGS{'Attach'}"; - # since CGI.pm deutf8izes the magic field, we need to add it back. - Encode::_utf8_on($subject); # strip leading directories $subject =~ s#^.*[\\/]##; diff --git a/rt/html/Ticket/Display.html b/rt/html/Ticket/Display.html index cf32dce9d..276cee62a 100644 --- a/rt/html/Ticket/Display.html +++ b/rt/html/Ticket/Display.html @@ -22,20 +22,20 @@ %# %# END LICENSE BLOCK <& /Elements/Header, - Title => loc("#[_1]: [_2]", $Ticket->Id, $Ticket->Subject) &> + Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject) &> <& /Ticket/Elements/Tabs, - Ticket => $Ticket, - current_tab => 'Ticket/Display.html?id='.$Ticket->id, - Title => loc("#[_1]: [_2]", $Ticket->Id, $Ticket->Subject) &> + Ticket => $TicketObj, + current_tab => 'Ticket/Display.html?id='.$TicketObj->id, + Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject) &> <& /Elements/ListActions, actions => \@Actions &> -<& /Ticket/Elements/ShowSummary, Ticket => $Ticket &> +<& /Ticket/Elements/ShowSummary, Ticket => $TicketObj &> <BR> <& /Ticket/Elements/ShowHistory , - Ticket => $Ticket, + Ticket => $TicketObj, Collapsed => $ARGS{'Collapsed'}, ShowHeaders => $ARGS{'ShowHeaders'} &> @@ -45,14 +45,13 @@ $id => undef $Create => undef $ShowHeaders => undef $Collapsed => undef +$TicketObj => undef </%ARGS> <%INIT> - my ($linkid, $message, $tid, $Ticket, @Actions); + my ($linkid, $message, $tid, @Actions); -$Ticket = new RT::Ticket($session{'CurrentUser'}); - -unless ($id) { +unless ($id || $TicketObj) { Abort('No ticket specified'); } @@ -67,47 +66,50 @@ if ($ARGS{'id'} eq 'new') { unless ($Queue->CurrentUserHasRight('CreateTicket')) { Abort('You have no permission to create tickets in that queue.'); } - ($Ticket, @Actions) = - CreateTicket(Attachments => $session{'Attachments'}, %ARGS); + ($TicketObj, @Actions) = + CreateTicket(Attachments => $session{'Attachments'}, %ARGS); delete $session{'Attachments'}; - unless ($Ticket->CurrentUserHasRight('ShowTicket')) { - Abort("No permission to view newly created ticket #".$Ticket->id."."); - } + unless ($TicketObj->CurrentUserHasRight('ShowTicket')) { + Abort("No permission to view newly created ticket #".$TicketObj->id."."); + } # }}} -} +} else { + if (!$TicketObj) { -else { - $Ticket = LoadTicket($ARGS{'id'}); - unless ($Ticket->CurrentUserHasRight('ShowTicket')) { - Abort("No permission to view ticket"); - } + $TicketObj = RT::Ticket->new($session{'CurrentUser'}); + $TicketObj = LoadTicket($ARGS{'id'}); + unless ($TicketObj->CurrentUserHasRight('ShowTicket')) { + Abort("No permission to view ticket"); + } + } -if (defined $ARGS{'Action'}) { - if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) { - my $action = $1; - my ($res, $msg)=$Ticket->$action(); - push(@Actions, $msg); - } -} + if (defined $ARGS{'Action'}) { + if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) { + my $action = $1; + my ($res, $msg)=$TicketObj->$action(); + push(@Actions, $msg); + } + } - if ( $ARGS{'UpdateContent'} ) { + if ( $ARGS{'UpdateContent'} || $session{'Attachments'}) { $ARGS{'UpdateContent'} =~ s/\r\n/\n/g; - if ( $ARGS{'UpdateContent'} ne '' - && $ARGS{'UpdateContent'} ne "-- \n" - . $session{'CurrentUser'}->UserObj->Signature ) { + if ( $session{'Attachments'} || + ( $ARGS{'UpdateContent'} ne '' + && $ARGS{'UpdateContent'} ne "-- \n" + . $session{'CurrentUser'}->UserObj->Signature )) { $ARGS{UpdateAttachments} = $session{'Attachments'}; ProcessUpdateMessage( ARGSRef => \%ARGS, Actions => \@Actions, - TicketObj => $Ticket ); + TicketObj => $TicketObj ); delete $session{'Attachments'}; } } -#Process status updates -my @BasicActions = ProcessTicketBasics(ARGSRef => \%ARGS, TicketObj=>$Ticket); -my @results = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS); + #Process status updates + my @BasicActions = ProcessTicketBasics(ARGSRef => \%ARGS, TicketObj=>$TicketObj); + my @results = ProcessTicketLinks( TicketObj => $TicketObj, ARGSRef => \%ARGS); -push (@Actions, @BasicActions, @results); + push (@Actions, @BasicActions, @results); } </%INIT> diff --git a/rt/html/Ticket/Elements/AddWatchers b/rt/html/Ticket/Elements/AddWatchers index e9f651593..96dd38f08 100644 --- a/rt/html/Ticket/Elements/AddWatchers +++ b/rt/html/Ticket/Elements/AddWatchers @@ -77,6 +77,7 @@ my ($msg, $Users, $Groups); if ($UserString) { $Users = RT::Users->new($session{'CurrentUser'}); $Users->Limit(FIELD => $UserField, VALUE => $UserString, OPERATOR => $UserOp); + $Users->LimitToPrivileged if $PrivilegedOnly; } if ($GroupString) { @@ -94,4 +95,5 @@ $UserString => undef $GroupField => 'Name' $GroupOp => '=' $GroupString => undef +$PrivilegedOnly => undef </%ARGS> diff --git a/rt/html/Ticket/Elements/EditCustomField b/rt/html/Ticket/Elements/EditCustomField index 1fc7d4388..16348061e 100644 --- a/rt/html/Ticket/Elements/EditCustomField +++ b/rt/html/Ticket/Elements/EditCustomField @@ -30,6 +30,8 @@ size="<%$Cols%>" % if ($TicketObj) { value="<%$Values->Count ? $Values->First->Content : ''%>" +% } elsif ($Default) { + value="<%$Default ? $Default : ''%>" % } > % } elsif ($CustomField->Type eq 'FreeformMultiple') { @@ -38,6 +40,8 @@ % while (my $value = $Values->Next ) { % $content .= $value->Content; % } +% } elsif ($Default) { + value="<%$Default ? $Default : ''%>" % } <input type="hidden" name="<%$NamePrefix%><%$CustomField->Id%>-Values-Magic" value="1"> <textarea cols=<%$Cols%> rows=<%$Rows%> name="<%$NamePrefix%><%$CustomField->Id%>-Values"><%$content%></textarea> diff --git a/rt/html/Ticket/Elements/EditLinks b/rt/html/Ticket/Elements/EditLinks index 7a522dda6..bdb8a6b7d 100644 --- a/rt/html/Ticket/Elements/EditLinks +++ b/rt/html/Ticket/Elements/EditLinks @@ -35,10 +35,8 @@ <td class="labeltop"><&|/l&>Depends on</&>:</td> <td class="value"> % while (my $link = $Ticket->DependsOn->Next) { -% my $member = $link->TargetObj; <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>"> - <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> - [<%$member->Status%>]<br> + <& ShowLink, URI => $link->TargetURI &><br> % } </td> </tr> @@ -48,8 +46,7 @@ % while (my $link = $Ticket->DependedOnBy->Next) { % my $member = $link->BaseObj; <INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-"> - <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> - [<%$member->Status%>]<br> + <& ShowLink, URI => $link->BaseURI &><br> % } </td> </tr> @@ -57,10 +54,8 @@ <td class="labeltop"><&|/l&>Parents</&>:</td> <td class="value"> % while (my $link = $Ticket->MemberOf->Next) { -% my $member = $link->TargetObj; <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>"> - <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> - [<%$member->Status%>]<br> + <& ShowLink, URI => $link->TargetURI &><br> % } </td> </tr> @@ -69,9 +64,7 @@ <td class="value"> % while (my $link = $Ticket->Members->Next) { <INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-"> -% my $member = $link->BaseObj; - <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> - [<%$member->Status%>]<br> + <& ShowLink, URI => $link->BaseURI &><br> % } </td> </tr> @@ -80,12 +73,7 @@ <td class="value"> % while (my $link = $Ticket->RefersTo->Next) { <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>"> -% if ($link->TargetURI->IsLocal) { -% my $member = $link->TargetObj; - <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br> -% } else { - <A HREF="<%$link->TargetURI->Resolver->HREF%>"><%$link->TargetURI->Resolver->AsString%></A><br> -% } + <& ShowLink, URI => $link->TargetURI &><br> %} </td> </tr> @@ -94,12 +82,7 @@ <td class="value"> % while (my $link = $Ticket->ReferredToBy->Next) { <INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-"> -% if ($link->BaseURI->IsLocal) { -% my $member = $link->BaseObj; - <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br> -% } else { - <A HREF="<%$link->BaseURI->Resolver->HREF%>"><%$link->BaseURI->Resolver->AsString%></A><br> -%} + <& ShowLink, URI => $link->BaseURI &><br> % } </td> </tr> diff --git a/rt/html/Ticket/Elements/EditPeople b/rt/html/Ticket/Elements/EditPeople index 1ab8f4ace..a1fc0111a 100644 --- a/rt/html/Ticket/Elements/EditPeople +++ b/rt/html/Ticket/Elements/EditPeople @@ -37,7 +37,7 @@ <& AddWatchers, Ticket => $Ticket, UserString => $UserString, UserOp => $UserOp, UserField => $UserField, GroupString => $GroupString, GroupOp => $GroupOp, - GroupField => $GroupField &> + GroupField => $GroupField, PrivilegedOnly => $PrivilegedOnly &> </TD><TD VALIGN=TOP> <h3><&|/l&>Owner</&></h3> <&|/l&>Owner</&>: <& /Elements/SelectOwner, Name => 'Owner', QueueObj => $Ticket->QueueObj, TicketObj => $Ticket, Default => $Ticket->OwnerObj->Id &> @@ -64,5 +64,6 @@ $UserString => undef $GroupField => undef $GroupOp => undef $GroupString => undef +$PrivilegedOnly => undef $Ticket => undef </%ARGS> diff --git a/rt/html/Ticket/Elements/ShowAttachments b/rt/html/Ticket/Elements/ShowAttachments index 22b60d11b..590a011fb 100644 --- a/rt/html/Ticket/Elements/ShowAttachments +++ b/rt/html/Ticket/Elements/ShowAttachments @@ -47,7 +47,7 @@ if ($size) { </%PERL> <li><font <%$fontsize%>> - <A HREF="<%$RT::WebPath%>/Ticket/Attachment/<%$rev->TransactionObj->Id%>/<%$rev->Id%>/<%$rev->Filename%>"><%$rev->CreatedAsString%> (<% $size %>)</a></font></li> + <A HREF="<%$RT::WebPath%>/Ticket/Attachment/<%$rev->TransactionObj->Id%>/<%$rev->Id%>/<%$rev->Filename | u%>"><%$rev->CreatedAsString%> (<% $size %>)</a></font></li> % } % $fontsize='size="-2"'; % } @@ -63,6 +63,9 @@ my %documents; my $transactions = $Ticket->Transactions(); while (my $trans = $transactions->Next()) { my $attachments = $trans->Attachments(); + $attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId) ); + $attachments->Limit(FIELD => 'Filename', OPERATOR => 'IS NOT', VALUE => 'NULL', QUOTEVALUE => 0, ENTRYAGGREGATOR => 'AND'); + $attachments->Limit(FIELD => 'Filename', OPERATOR => '!=', VALUE => '', ENTRYAGGREGATOR => 'AND'); while (my $attach = $attachments->Next()) { next unless ($attach->Filename()); # most recent at the top diff --git a/rt/html/Ticket/Elements/ShowDates b/rt/html/Ticket/Elements/ShowDates index da7f75bb6..b09b4bf7b 100644 --- a/rt/html/Ticket/Elements/ShowDates +++ b/rt/html/Ticket/Elements/ShowDates @@ -21,6 +21,7 @@ %# %# %# END LICENSE BLOCK + <TABLE> <TR> <TD class="label"><&|/l&>Created</&>:</TD> @@ -35,7 +36,7 @@ <TD class="value"><% $Ticket->StartedObj->AsString %></TD> </TR> <TR> - <TD class="label"><&|/l&>Last Contact</&>:</TD> + <TD class="label"><a href="Display.html?id=<%$Ticket->id%>&Action=SetTold"><&|/l&>Last Contact</&></a>:</TD> <TD class="value"><% $Ticket->ToldObj->AsString %></TD> </TR> <TR> @@ -48,9 +49,15 @@ </TR> <TR> <TD class="label"><&|/l&>Updated</&>:</TD> - <TD class="value"><A HREF="#lasttrans"><% $Ticket->LastUpdated ? (loc("[_1] by [_2]", $Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)) : loc("Never") | h %></a></TD> +% my $UpdatedString = $Ticket->LastUpdated ? (loc("[_1] by [_2]", $Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)) : loc("Never"); +% if ($UpdatedLink) { + <TD class="value"><A HREF="#lasttrans"><% $UpdatedString | h %></a></TD> +% } else { + <TD class="value"><% $UpdatedString | h %></TD> +% } </TR> </TABLE> <%ARGS> $Ticket => undef +$UpdatedLink => 1 </%ARGS> diff --git a/rt/html/Ticket/Elements/ShowHistory b/rt/html/Ticket/Elements/ShowHistory index 2958f8706..194be9b37 100644 --- a/rt/html/Ticket/Elements/ShowHistory +++ b/rt/html/Ticket/Elements/ShowHistory @@ -62,7 +62,7 @@ else { % if ($Transactions->IsLast) { <a name="lasttrans"></a> % } - <& ShowTransaction, Ticket => $Ticket, Transaction => $Transaction, ShowHeaders => $ShowHeaders, Collapsed => $Collapsed, RowNum => $i, ShowTitleBarCommands => $ShowTitleBarCommands &> + <& ShowTransaction, Ticket => $Ticket, Transaction => $Transaction, ShowHeaders => $ShowHeaders, Collapsed => $Collapsed, RowNum => $i, ShowTitleBarCommands => $ShowTitleBarCommands, %ARGS &> % } </TABLE> % if ($ShowDisplayModes or $ShowTitle) { diff --git a/rt/html/Ticket/Elements/ShowMessageStanza b/rt/html/Ticket/Elements/ShowMessageStanza index b0998068f..8e3045a36 100644 --- a/rt/html/Ticket/Elements/ShowMessageStanza +++ b/rt/html/Ticket/Elements/ShowMessageStanza @@ -21,6 +21,8 @@ %# %# %# END LICENSE BLOCK +% if (ref($Message)) { +<font color="<%$colors[$Depth]%>"> <%perl> foreach my $stanza (@$Message) { if ( ref $stanza eq "ARRAY" ) { @@ -36,8 +38,16 @@ foreach my $stanza (@$Message) { $content =~ s/\n/<br>/gi; </%perl> -<font color="<%$colors[$Depth]%>"><%$content |n%><br></font> +<%$content |n%><br> % } +% } # end foreach +</font> +% } else { +% my $content = $Message; +% RT::Interface::Web::EscapeUTF8(\$content); +% $m->comp('/Elements/Callback', content => \$content, %ARGS); +% $content =~ s/\n/<br>/gi; +<%$content |n%><br> % } <%INIT> use URI::URL; diff --git a/rt/html/Ticket/Elements/ShowPeople b/rt/html/Ticket/Elements/ShowPeople index 0b8026949..160da70d9 100644 --- a/rt/html/Ticket/Elements/ShowPeople +++ b/rt/html/Ticket/Elements/ShowPeople @@ -27,15 +27,15 @@ <td class="value"><%$Ticket->OwnerObj->Name%></td> </tr> <tr> - <td class="label"><&|/l&>Requestors</&>:</td> + <td class="labeltop"><&|/l&>Requestors</&>:</td> <td class="value"><%$Ticket->RequestorAddresses%></td> </tr> <tr> - <td class="label"><&|/l&>Cc</&>:</td> + <td class="labeltop"><&|/l&>Cc</&>:</td> <td class="value"><%$Ticket->CcAddresses%></td> </tr> <tr> - <td class="label"><&|/l&>AdminCc</&>:</td> + <td class="labeltop"><&|/l&>AdminCc</&>:</td> <td class="value"><%$Ticket->AdminCcAddresses%></td> </tr> </table> diff --git a/rt/html/Ticket/Elements/ShowTransaction b/rt/html/Ticket/Elements/ShowTransaction index f2f89d35c..2d710fcbc 100644 --- a/rt/html/Ticket/Elements/ShowTransaction +++ b/rt/html/Ticket/Elements/ShowTransaction @@ -38,8 +38,6 @@ unless ($Collapsed) { $attachments->GotoFirstItem; while (my $message=$attachments->Next) { - #we don't want to show any empty transactions, unless they have kids - next unless ($message->ContentLength || $message->Children->Count); my ($headers, $quoted); if ($ShowHeaders && ($ShowHeaders == $Ticket->Id)) { @@ -53,11 +51,18 @@ unless ($Collapsed) { eval {$headers =~ s/^([^:]+)(?=:)/loc($1)/em; } # we eval here to catch errors when 5.6 panics } # 13456 is a random # of about the biggest size we want to see inline text - my $MAX_INLINE_BODY = 13456; + # It's here to catch anyone who hasn't updated RT_Config.pm since this + # constant was moved out there. + my $MAX_INLINE_BODY = $RT::MaxInlineBody || 13456; if ($message->ContentType =~ m{^(text/plain|message|text$)}i && $message->ContentLength < $MAX_INLINE_BODY ) { + eval { require Text::Quoted; - $quoted = Text::Quoted::extract($message->Content); + $quoted = Text::Quoted::extract($message->Content); + }; + if ($@) { + $quoted = $message->Content; + } } </%PERL> @@ -69,7 +74,12 @@ unless ($Collapsed) { <PRE> <& ShowMessageHeaders, Headers => $headers, Transaction => $Transaction &> </PRE> +% if (!length($quoted) && $message->ContentType =~ m#^text/#) { +<blockquote><i><&|/l&>Message body not shown because it is too large or is not plain text.</&><br> +<&|/l&>You can access it with the Download button on the right.</&></i></blockquote> +% } else { <& ShowMessageStanza, Depth => 0, Message => $quoted, Transaction => $Transaction &> +% } </span> </TD> <TD VALIGN=TOP ALIGN=RIGHT> @@ -78,7 +88,7 @@ unless ($Collapsed) { <BR> % } <%PERL> -my $size = $message->ContentLength; +my $size = $message->ContentLength or next; if ($size) { if ($size > 1024) { @@ -88,7 +98,7 @@ if ($size) { $size = loc("[_1]b", $size); } </%PERL> -<font size=-1><A HREF="<%$RT::WebPath%>/Ticket/Attachment/<%$Transaction->Id%>/<%$message->Id%>/<%$message->Filename%>"><&|/l&>Download</&> <% $message->Filename|| loc('(untitled)') %></a> <% $size %></font> +<font size=-1><A HREF="<%$AttachPath%>/<%$Transaction->Id%>/<%$message->Id%>/<%$message->Filename | u%>"><&|/l&>Download</&> <% $message->Filename|| loc('(untitled)') %></a> <% $size %></font> % } </TD> </TR> @@ -104,6 +114,7 @@ $ShowHeaders => 0 $Collapsed => undef $ShowTitleBarCommands => 1 $RowNum => 1 +$AttachPath => $RT::WebPath."/Ticket/Attachment" </%ARGS> <%INIT> @@ -147,6 +158,7 @@ if ($Transaction->TimeTaken > 0) { $TimeTaken = $Transaction->TimeTaken." min" } my $attachments = $Transaction->Attachments; +$attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId) ); my $titlebar_commands=' '; diff --git a/rt/html/Ticket/Elements/Tabs b/rt/html/Ticket/Elements/Tabs index 81c92e8c2..cba45df91 100644 --- a/rt/html/Ticket/Elements/Tabs +++ b/rt/html/Ticket/Elements/Tabs @@ -45,11 +45,17 @@ my $id = $Ticket->id(); if ( defined $session{'tickets'} ) { + # we have to update session data if we get new ItemMap + my $updatesession = 1 unless($session{'tickets'}->{'item_map'}); -my $item_map = $session{'tickets'}->ItemMap; + my $item_map = $session{'tickets'}->ItemMap; - # Don't $current_toptab = display prev links if we're on the first ticket + if ($updatesession) { + $session{'i'}++; + $session{'tickets'}->PrepForSerialization(); + } + # Don't $current_toptab = display prev links if we're on the first ticket if ($item_map->{$Ticket->Id}->{prev}) { $searchtabs->{'_a'} = { class => "nav", diff --git a/rt/html/Ticket/Modify.html b/rt/html/Ticket/Modify.html index c97fd0994..e504a3cba 100644 --- a/rt/html/Ticket/Modify.html +++ b/rt/html/Ticket/Modify.html @@ -46,7 +46,7 @@ my $CustomFields = $TicketObj->QueueObj->CustomFields(); $m->comp('/Elements/Callback', TicketObj => $TicketObj, CustomFields => $CustomFields, %ARGS); my @results = ProcessTicketBasics(TicketObj => $TicketObj, ARGSRef => \%ARGS); -my @cf_results = ProcessTicketCustomFieldUpdates(ARGSRef => \%ARGS); +my @cf_results = ProcessTicketCustomFieldUpdates(TicketObj => $TicketObj, ARGSRef => \%ARGS); push (@results, @cf_results); # TODO: display the results, even if we can't display the ticket diff --git a/rt/html/Ticket/ModifyAll.html b/rt/html/Ticket/ModifyAll.html index a50689398..1163f3fa5 100644 --- a/rt/html/Ticket/ModifyAll.html +++ b/rt/html/Ticket/ModifyAll.html @@ -115,7 +115,7 @@ my (@wresults, @results, @dresults, @lresults, @cf_results); unless ($OnlySearchForPeople) { @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS); @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS); - @cf_results = ProcessTicketCustomFieldUpdates(ARGSRef => \%ARGS); + @cf_results = ProcessTicketCustomFieldUpdates( TicketObj => $Ticket, ARGSRef => \%ARGS); @dresults = ProcessTicketDates( TicketObj => $Ticket, ARGSRef => \%ARGS); @lresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS); diff --git a/rt/html/Ticket/ModifyPeople.html b/rt/html/Ticket/ModifyPeople.html index 2e41664d9..debd27a97 100644 --- a/rt/html/Ticket/ModifyPeople.html +++ b/rt/html/Ticket/ModifyPeople.html @@ -44,7 +44,7 @@ my (@results, @wresults); my $Ticket = LoadTicket($id); # if we're trying to search for watchers and nothing else -unless ($OnlySearchForPeople) { +unless ($OnlySearchForPeople or $OnlySearchForGroup) { @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS); @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS); } @@ -56,6 +56,7 @@ push @results, @wresults; <%ARGS> $OnlySearchForPeople => undef +$OnlySearchForGroup => undef $UserField => undef $UserOp => undef $UserString => undef diff --git a/rt/html/Ticket/Update.html b/rt/html/Ticket/Update.html index e19aacf6a..ad3b21787 100644 --- a/rt/html/Ticket/Update.html +++ b/rt/html/Ticket/Update.html @@ -23,7 +23,7 @@ %# END LICENSE BLOCK <& /Elements/Header, Title => $title &> <& /Ticket/Elements/Tabs, - Ticket => $Ticket , + Ticket => $TicketObj, Title=> $title &> <FORM ACTION="Update.html" NAME="TicketUpdate" @@ -35,20 +35,20 @@ <TABLE> <TR><TD> -<a href="ModifyPeople.html?id=<%$Ticket->Id%>"><&|/l&>Ticket watchers</&></A></TD><TD align=right> +<a href="ModifyPeople.html?id=<%$TicketObj->Id%>"><&|/l&>Ticket watchers</&></A></TD><TD align=right> <&|/l&>Requestor</&>: </TD><TD> -<b><% $Ticket->RequestorAddresses %></b> +<b><% $TicketObj->RequestorAddresses %></b> </TD></TR> <TR><TD> </TD><TD align=right> <&|/l&>Cc</&>: </TD><TD> -<b><% $Ticket->CcAddresses %></b> +<b><% $TicketObj->CcAddresses %></b> </TD></TR> <TR><TD> </TD><TD align=right> <&|/l&>AdminCc</&>: </TD><TD> -<b><% $Ticket->AdminCcAddresses %></b> +<b><% $TicketObj->AdminCcAddresses %></b> </TD></TR> </TR> </TABLE> @@ -60,7 +60,7 @@ <td> <& /Elements/SelectStatus, Name=>"Status", Default => $DefaultStatus &> <&|/l&>Owner</&>: -<& /Elements/SelectOwner, Name=>"Owner", Default => ($ARGS{'Owner'} || $Ticket->OwnerObj->Id()), QueueObj => $Ticket->QueueObj, TicketObj => $Ticket &> +<& /Elements/SelectOwner, Name=>"Owner", Default => ($ARGS{'Owner'} || $TicketObj->OwnerObj->Id()), QueueObj => $TicketObj->QueueObj, TicketObj => $TicketObj &> <&|/l&>Worked</&>: <input size=4 name="UpdateTimeWorked" value="<% $ARGS{UpdateTimeWorked}%>"> <&|/l&>minutes</&></td></tr> <tr><td align=right><&|/l&>Update Type</&>:</td> <td><select name="UpdateType"> @@ -72,7 +72,7 @@ % } </select> </td></tr> -<tr><td align=right><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size=60 value="<% ($ARGS{UpdateSubject}) ? $ARGS{UpdateSubject} : $Ticket->Subject()%>"></td></tr> +<tr><td align=right><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size=60 value="<% ($ARGS{UpdateSubject}) ? $ARGS{UpdateSubject} : $TicketObj->Subject()%>"></td></tr> <tr><td align=right><&|/l&>Cc</&>:</td><td> <input name="UpdateCc" size=60 value=<% $ARGS{UpdateCc} %>><BR> <i><font size=-2> @@ -101,12 +101,12 @@ value=<% $ARGS{UpdateCc} %>><BR> <& /Elements/Callback, _CallbackName => 'BeforeMessageBox', %ARGS &> % if (exists $ARGS{UpdateContent}) { % delete $ARGS{'QuoteTransaction'}; -<& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, %ARGS&> +<& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, IncludeSignature => 0, %ARGS&> % } else { <& /Elements/MessageBox, Name=>"UpdateContent", %ARGS &> % } </td></tr> - <INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>"><br> + <INPUT TYPE=HIDDEN NAME=id VALUE="<%$TicketObj->Id%>"><br> </table> @@ -123,10 +123,10 @@ my $CanRespond = 0; my $CanComment = 0; my $title; -my $Ticket = LoadTicket($id); +my $TicketObj = LoadTicket($id); unless($DefaultStatus){ - $DefaultStatus=($ARGS{'Status'} ||$Ticket->Status()); + $DefaultStatus=($ARGS{'Status'} ||$TicketObj->Status()); } if ($DefaultStatus =~ '^new$'){ @@ -134,9 +134,9 @@ if ($DefaultStatus =~ '^new$'){ } if ($DefaultStatus eq 'resolved') { - $title = loc("Resolve ticket #[_1] ([_2])", $Ticket->id, $Ticket->Subject); + $title = loc("Resolve ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject); } else { - $title = loc("Update ticket #[_1] ([_2])", $Ticket->id, $Ticket->Subject); + $title = loc("Update ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject); } # Things needed in the template - we'll do the processing here, just @@ -150,11 +150,11 @@ if (($Action eq 'Comment') or ($ARGS{'UpdateType'} eq 'private')) { } -$CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or - $Ticket->CurrentUserHasRight('ModifyTicket') ); +$CanRespond = 1 if ( $TicketObj->CurrentUserHasRight('ReplyToTicket') or + $TicketObj->CurrentUserHasRight('ModifyTicket') ); -$CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or - $Ticket->CurrentUserHasRight('ModifyTicket') ); +$CanComment = 1 if ( $TicketObj->CurrentUserHasRight('CommentOnTicket') or + $TicketObj->CurrentUserHasRight('ModifyTicket') ); # {{{ deal with deleting uploaded attachments @@ -193,7 +193,7 @@ unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) { # }}} if ( exists $ARGS{SubmitTicket} ) { - $m->comp('Display.html', %ARGS); + $m->comp('Display.html', TicketObj => $TicketObj, %ARGS); return; } </%INIT> diff --git a/rt/html/User/Prefs.html b/rt/html/User/Prefs.html index b89fc40ae..c2746a38c 100644 --- a/rt/html/User/Prefs.html +++ b/rt/html/User/Prefs.html @@ -38,21 +38,44 @@ <& /Elements/TitleBoxStart, title => loc('Identity') &> <input type=hidden name="Name" value="<%$UserObj->Name%>"> -<&|/l&>Email</&>: <input name="EmailAddress" value="<%$UserObj->EmailAddress%>"> -<BR> -<&|/l&>Real Name</&>: <input name="RealName" value="<%$UserObj->RealName%>"> -<BR> -<&|/l&>Nickname</&>: <input name="NickName" value="<%$UserObj->NickName%>"> +<table callspacing=0 cellpadding=0> + <tr> + <td class=label><&|/l&>Email</&>: </td> + <td class=value><input name="EmailAddress" value="<%$UserObj->EmailAddress%>"></td> + </tr> + <tr> + <td class=label><&|/l&>Real Name</&>:</td> + <td class=value><input name="RealName" value="<%$UserObj->RealName%>"></td> </tr> + <tr> + <td class=label><&|/l&>Nickname</&>:</td> + <td class=value><input name="NickName" value="<%$UserObj->NickName%>"></td> + </tr> + <tr> + <td class=label><&|/l&>Language</&>:</td> + <td class=value><& /Elements/SelectLang, Name => 'Lang', Default => $UserObj->Lang &></td> + </tr> +</table> <& /Elements/TitleBoxEnd &> <br> <& /Elements/TitleBoxStart, title => loc('Phone numbers') &> -<&|/l&>Residence</&>: <input name="HomePhone" value="<%$UserObj->HomePhone%>" size=13> -<BR> -<&|/l&>Work</&>: <input name="WorkPhone" value="<%$UserObj->WorkPhone%>" size=13> -<BR> -<&|/l&>Mobile</&>: <input name="MobilePhone" value="<%$UserObj->MobilePhone%>" size=13> -<BR> -<&|/l&>Pager</&>: <input name="PagerPhone" value="<%$UserObj->PagerPhone%>" size=13> +<table callspacing=0 cellpadding=0> + <tr> + <td class=label><&|/l&>Residence</&>:</td> + <td class=value><input name="HomePhone" value="<%$UserObj->HomePhone%>" size=13></td> + </tr> + <tr> + <td class=label><&|/l&>Work</&>:</td> + <td class=value><input name="WorkPhone" value="<%$UserObj->WorkPhone%>" size=13></td> + </tr> + <tr> + <td class=label><&|/l&>Mobile</&>:</td> + <td class=value><input name="MobilePhone" value="<%$UserObj->MobilePhone%>" size=13></td> + </tr> + <tr> + <td class=label><&|/l&>Pager</&>:</td> + <td class=value><input name="PagerPhone" value="<%$UserObj->PagerPhone%>" size=13></td> + </tr> +</table> <& /Elements/TitleBoxEnd &> </TD> <TD VALIGN=TOP> @@ -60,44 +83,58 @@ <& /Elements/TitleBoxStart, title => loc('Password') &> <TABLE> <TR> -<TD ALIGN=RIGHT> +<TD class=label> <&|/l&>New Password</&>: </TD> -<TD ALIGN=LEFT> +<TD class=value> <input type=password name="Pass1"> </TD> </TR> -<TR><TD ALIGN=RIGHT> +<TR><TD class=label> <&|/l&>Retype Password</&>: </TD> -<TD> +<TD class=value> <input type=password name="Pass2"> </TD> </TR> </TABLE> -% } <& /Elements/TitleBoxEnd &> +% } </TD> <TR> <TD VALIGN=TOP> <& /Elements/TitleBoxStart, title => loc('Location') &> -<&|/l&>Organization</&>: <input name="Organization" value="<%$UserObj->Organization%>"> -<BR> -<&|/l&>Address1</&>: <input name="Address1" value="<%$UserObj->Address1%>"> -<BR> -<&|/l&>Address2</&>: <input name="Address2" value="<%$UserObj->Address2%>"> -<BR> -<&|/l&>City</&>: <input name="City" value="<%$UserObj->City%>" size=14> - -<&|/l&>State</&>: <input name="State" value="<%$UserObj->State%>" size=3> - -<&|/l&>Zip</&>: <input name="Zip" value="<%$UserObj->Zip%>" size=9> -<BR> -<&|/l&>Country</&>: <input name="Country" value="<%$UserObj->Country%>"> -<BR> - - +<table callspacing=0 cellpadding=0> + <tr> + <td class=label><&|/l&>Organization</&>:</td> + <td class=value><input name="Organization" value="<%$UserObj->Organization%>"></td> + </tr> + <tr> + <td class=label><&|/l&>Address1</&>:</td> + <td class=value><input name="Address1" value="<%$UserObj->Address1%>"></td> + </tr> + <tr> + <td class=label><&|/l&>Address2</&>:</td> + <td class=value><input name="Address2" value="<%$UserObj->Address2%>"></td> + </tr> + <tr> + <td class=label><&|/l&>City</&>:</td> + <td><input name="City" value="<%$UserObj->City%>" size=14></td> + </tr> + <tr> + <td class=label><&|/l&>State</&>:</td> + <td class=value><input name="State" value="<%$UserObj->State%>" size=3></td> + </tr> + <tr> + <td class=label><&|/l&>Zip</&>:</td> + <td class=value><input name="Zip" value="<%$UserObj->Zip%>" size=9></td> + </tr> + <tr> + <td class=label><&|/l&>Country</&>:</td> + <td class=value><input name="Country" value="<%$UserObj->Country%>"></td> + </tr> +</table> <& /Elements/TitleBoxEnd &> </TD> </TR> @@ -147,12 +184,13 @@ if ($UserObj->Id) { Organization RealName NickName Lang EmailEncoding WebEncoding ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1 - Address2 City State Zip Country + Address2 City State Zip Country Lang ); my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields, Object => $UserObj, ARGSRef => \%ARGS ); + $session{'CurrentUser'}->LanguageHandle($Lang) if $Lang; push (@results,@fieldresults); diff --git a/rt/html/autohandler b/rt/html/autohandler index ce8b7569e..b2a407add 100644 --- a/rt/html/autohandler +++ b/rt/html/autohandler @@ -27,18 +27,24 @@ $RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth; -local *session; +local *session unless $m->is_subrequest; # avoid reentrancy, as suggested by masonbook + +# Disable AutoFlush using an attribute +if ($m->request_comp->attr_exists('AutoFlush')) { + $m->autoflush($m->request_comp->attr('AutoFlush')); +} + %ARGS = map { - # if they've passed multiple values, they'll be an array. if they've passed just one, a scalar - # whatever they are, mark them as utf8 + # if they've passed multiple values, they'll be an array. if they've + # passed just one, a scalar whatever they are, mark them as utf8 my $type = ref($_); (!$type) ? Encode::decode(utf8 => $_, Encode::FB_PERLQQ) : - ($type eq 'ARRAY') + ($type eq 'ARRAY') ? [ map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] : - ($type eq 'HASH') + ($type eq 'HASH') ? { map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_ -} %ARGS; + } %ARGS; if ($ARGS{'Debug'}) { require Time::HiRes; @@ -65,69 +71,95 @@ if ($m->base_comp->path =~ '^/+NoAuth/' || $m->abort(); } -# If RT is configured for external auth, let's get REMOTE_USER -elsif ($RT::WebExternalAuth and length($ENV{'REMOTE_USER'})) { - my $orig_user = $user; - - $user = $ENV{'REMOTE_USER'}; - $session{'CurrentUser'} = RT::CurrentUser->new(); - my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load'; - - if ($^O eq 'MSWin32' and $RT::WebExternalGecos) { - my $NodeName = Win32::NodeName(); - $user =~ s/^\Q$NodeName\E\\//i; - } - - $session{'CurrentUser'}->$load_method($user); - - if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) { - # Create users on-the-fly with default attributes - - my $UserObj = RT::User->new(RT::CurrentUser->new('root')); - - my ($val, $msg) = $UserObj->Create( - %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}}, - Name => $user, - Gecos => $user, - ); - - if ($val) { - $UserObj->SetPrivileged(1); - - if ($^O !~ /^(?:riscos|MacOS|MSWin32|dos|os2)$/) { - # Populate fields with information from Unix /etc/passwd - - my ($comments, $realname) = (getpwnam($user))[5, 6]; - $UserObj->SetComments($comments) if defined $comments; - $UserObj->SetRealName($realname) if defined $realname; +# If RT is configured for external auth, let's go through and get REMOTE_USER +elsif ( $RT::WebExternalAuth ) { + + # do we actually have a REMOTE_USER equivlent? + if ( RT::Interface::Web::WebCanonicalizeInfo() ) { + + my $orig_user = $user; + + $user = RT::Interface::Web::WebCanonicalizeInfo(); + $session{'CurrentUser'} = RT::CurrentUser->new(); + my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load'; + + if ($^O eq 'MSWin32' and $RT::WebExternalGecos) { + my $NodeName = Win32::NodeName(); + $user =~ s/^\Q$NodeName\E\\//i; + } + + $session{'CurrentUser'}->$load_method($user); + + if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) { + # Create users on-the-fly + + my $UserObj = RT::User->new(RT::CurrentUser->new('root')); + + my ($val, $msg) = $UserObj->Create( + %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}}, + Name => $user, + Gecos => $user, + ); + + if ($val) { + + # now get user specific information, to better create our user. + my $new_user_info = RT::Interface::Web::WebExternalAutoInfo($user); + + # set the attributes that have been defined. + # FIXME: this is a horrible kludge. I'm sure there's something cleaner + foreach my $attribute ('Name', 'Comments', 'Signature', 'EmailAddress', + 'PagerEmailAddress', 'FreeformContactInfo', + 'Organization', 'Disabled', 'Privileged', + 'RealName', 'NickName', 'Lang', 'EmailEncoding', + 'WebEncoding', 'ExternalContactInfoId', + 'ContactInfoSystem', 'ExternalAuthId', 'Gecos', + 'HomePhone', 'WorkPhone', 'MobilePhone', + 'PagerPhone', 'Address1', 'Address2', 'City', + 'State', 'Zip', 'Country') { + + my $method = "Set$attribute"; + $UserObj->$method($new_user_info->{$attribute}) + if( defined $new_user_info->{$attribute} ); + } + $session{'CurrentUser'}->Load($user); } - elsif ($^O eq 'MSWin32' and eval 'use Net::AdminMisc; 1') { - # Populate fields with information from NT domain controller + else { + # we failed to successfully create the user. abort abort abort. + delete $session{'CurrentUser'}; + $m->abort() unless $RT::WebFallbackToInternalAuth; + $m->comp('/Elements/Login', %ARGS, + Error=> loc('Cannot create user: [_1]', $msg)); } - - $session{'CurrentUser'}->Load($user); } - else { + + unless ( $session{'CurrentUser'}->Id() ) { delete $session{'CurrentUser'}; - $m->abort() unless $RT::WebFallbackToInternalAuth; - $m->comp('/Elements/Login', %ARGS, Error=> loc('Cannot create user: [_1]', $msg)); + $user = $orig_user; + + if ( $RT::WebExternalOnly ) { + $m->comp('/Elements/Login', %ARGS, + Error=> loc('You are not an authorized user')); + $m->abort(); + } } } - - unless ( $session{'CurrentUser'}->Id() ) { - delete $session{'CurrentUser'}; - $user = $orig_user; - - if ( $RT::WebExternalOnly ) { - $m->comp('/Elements/Login', %ARGS, Error=> loc('You are not an authorized user')); - $m->abort(); + elsif ($RT::WebFallbackToInternalAuth) { + unless (defined($session{'CurrentUser'})) { + $m->comp('/Elements/Login', %ARGS, + Error=> loc('XXX CHANGEME You are not an authorized user')); + $m->abort(); } + } else { + # WebExternalAuth is set, but we don't have a REMOTE_USER. abort + delete $session{'CurrentUser'} if defined $session{'CurrentUser'}; } } delete $session{'CurrentUser'} unless $session{'CurrentUser'} and defined $session{'CurrentUser'}->Id; + # Process per-page authentication callbacks $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'Auth'); diff --git a/rt/html/index.html b/rt/html/index.html index 39eac8d61..798972d94 100644 --- a/rt/html/index.html +++ b/rt/html/index.html @@ -53,7 +53,8 @@ if ( $ARGS{'q'} ) { $session{'tickets'} = RT::Tickets->new( $session{'CurrentUser'} ); if ( $query =~ m/\@/ ) { - $session{'tickets'}->LimitRequestor( VALUE => $query, + $session{'tickets'}->LimitWatcher( VALUE => $query, + TYPE => 'Requestor', OPERATOR => '=', ); $m->redirect("$RT::WebPath/Search/Listing.html"); } diff --git a/rt/lib/RT.pm b/rt/lib/RT.pm index 90c332bc0..7e941a2b2 100644 --- a/rt/lib/RT.pm +++ b/rt/lib/RT.pm @@ -47,7 +47,7 @@ use vars qw($VERSION $System $SystemUser $Nobody $Handle $Logger $MasonSessionDir ); -$VERSION = '3.0.4'; +$VERSION = '3.0.9'; $CORE_CONFIG_FILE = "/opt/rt3/etc/RT_Config.pm"; $SITE_CONFIG_FILE = "/opt/rt3/etc/RT_SiteConfig.pm"; @@ -117,13 +117,10 @@ sub LoadConfig { =cut sub Init { - require RT::Handle; + #Get a database connection - unless ($Handle && $Handle->dbh->ping) { - $Handle = RT::Handle->new(); - } - $Handle->Connect(); - + ConnectToDatabase(); + #RT's system user is a genuine database user. its id lives here $SystemUser = new RT::CurrentUser(); $SystemUser->LoadByName('RT_System'); @@ -137,6 +134,21 @@ sub Init { InitLogging(); } + +=head2 ConnectToDatabase + +Get a database connection + +=cut + +sub ConnectToDatabase { + require RT::Handle; + unless ($Handle && $Handle->dbh && $Handle->dbh->ping) { + $Handle = RT::Handle->new(); + } + $Handle->Connect(); +} + =head2 InitLogging Create the RT::Logger object. @@ -282,8 +294,15 @@ sub DropSetGIDPermissions { =head1 BUGS +Please report them to rt-3.0-bugs@fsck.com, if you know what's broken and have at least some idea of what needs to be fixed. +If you're not sure what's going on, report them rt-devel@lists.fsck.com. + =head1 SEE ALSO +L<RT::StyleGuide> +L<DBIx::SearchBuilder> + + =begin testing diff --git a/rt/lib/RT.pm.in b/rt/lib/RT.pm.in index 065734e2f..14c0d47ca 100644 --- a/rt/lib/RT.pm.in +++ b/rt/lib/RT.pm.in @@ -117,13 +117,10 @@ sub LoadConfig { =cut sub Init { - require RT::Handle; + #Get a database connection - unless ($Handle && $Handle->dbh->ping) { - $Handle = RT::Handle->new(); - } - $Handle->Connect(); - + ConnectToDatabase(); + #RT's system user is a genuine database user. its id lives here $SystemUser = new RT::CurrentUser(); $SystemUser->LoadByName('RT_System'); @@ -137,6 +134,21 @@ sub Init { InitLogging(); } + +=head2 ConnectToDatabase + +Get a database connection + +=cut + +sub ConnectToDatabase { + require RT::Handle; + unless ($Handle && $Handle->dbh && $Handle->dbh->ping) { + $Handle = RT::Handle->new(); + } + $Handle->Connect(); +} + =head2 InitLogging Create the RT::Logger object. @@ -282,8 +294,15 @@ sub DropSetGIDPermissions { =head1 BUGS +Please report them to rt-3.0-bugs@fsck.com, if you know what's broken and have at least some idea of what needs to be fixed. +If you're not sure what's going on, report them rt-devel@lists.fsck.com. + =head1 SEE ALSO +L<RT::StyleGuide> +L<DBIx::SearchBuilder> + + =begin testing diff --git a/rt/lib/RT/Action/AutoOpen.pm b/rt/lib/RT/Action/AutoOpen.pm index ea6da1952..7c8c2b89d 100644 --- a/rt/lib/RT/Action/AutoOpen.pm +++ b/rt/lib/RT/Action/AutoOpen.pm @@ -67,7 +67,7 @@ sub Commit { my $oldstatus = $self->TicketObj->Status(); $self->TicketObj->__Set( Field => 'Status', Value => 'open' ); $self->TicketObj->_NewTransaction( - Type => 'Set', + Type => 'Status', Field => 'Status', OldValue => $oldstatus, NewValue => 'open', diff --git a/rt/lib/RT/Action/Autoreply.pm b/rt/lib/RT/Action/Autoreply.pm index 81f7bddfa..f58b8f284 100755 --- a/rt/lib/RT/Action/Autoreply.pm +++ b/rt/lib/RT/Action/Autoreply.pm @@ -74,10 +74,18 @@ sub SetReturnAddress { } unless ($self->TemplateObj->MIMEObj->head->get('From')) { - my $friendly_name = $self->TicketObj->QueueObj->Description || - $self->TicketObj->QueueObj->Name; - $friendly_name =~ s/"/\\"/g; - $self->SetHeader('From', "\"$friendly_name\" <$replyto>"); + if ($RT::UseFriendlyFromLine) { + my $friendly_name = $self->TicketObj->QueueObj->Description || + $self->TicketObj->QueueObj->Name; + $friendly_name =~ s/"/\\"/g; + $self->SetHeader( 'From', + sprintf($RT::FriendlyFromLineFormat, + $self->MIMEEncodeString( $friendly_name, $RT::EmailOutputEncoding ), $replyto), + ); + } + else { + $self->SetHeader( 'From', $replyto ); + } } unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) { diff --git a/rt/lib/RT/Action/CreateTickets.pm b/rt/lib/RT/Action/CreateTickets.pm index 0ab206771..e1c6f4a9b 100644 --- a/rt/lib/RT/Action/CreateTickets.pm +++ b/rt/lib/RT/Action/CreateTickets.pm @@ -41,7 +41,7 @@ Create one or more tickets according to an externally supplied template. ===Create-Ticket: codereview Subject: Code review for {$Tickets{'TOP'}->Subject} - Depended-On-By: {$Tickets{'TOP'}->Id} + Depended-On-By: TOP Content: Someone has created a ticket. you should review and approve it, so they can finish their work ENDOFCONTENT @@ -84,13 +84,13 @@ After each ticket is created, it's stuffed into a hash called %Tickets so as to be available during the creation of other tickets during the same ScripAction. The hash is prepopulated with the ticket which triggered the ScripAction as $Tickets{'TOP'}; you can also access that ticket using the -shorthand $TOP. +shorthand TOP. A simple example: ===Create-Ticket: codereview Subject: Code review for {$Tickets{'TOP'}->Subject} - Depended-On-By: {$Tickets{'TOP'}->Id} + Depended-On-By: TOP Content: Someone has created a ticket. you should review and approve it, so they can finish their work ENDOFCONTENT @@ -128,8 +128,8 @@ A convoluted example Queue: Approvals Type: Approval AdminCc: {join ("\nAdminCc: ",@admins) } - Depended-On-By: {$Tickets{"TOP"}->Id} - Refers-To: {$Tickets{"TOP"}->Id} + Depended-On-By: TOP + Refers-To: TOP Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject} Due: {time + 86400} Content-Type: text/plain @@ -139,7 +139,7 @@ A convoluted example ENDOFCONTENT ===Create-Ticket: two Subject: Manager approval - Depended-On-By: {$Tickets{"TOP"}->Id} + Depended-On-By: TOP Refers-On: {$Tickets{"approval"}->Id} Queue: Approvals Content-Type: text/plain @@ -239,8 +239,8 @@ my $approvals = Queue: Approvals Type: Approval AdminCc: {join ("\nAdminCc: ",@admins) } -Depended-On-By: {$Tickets{"TOP"}->Id} -Refers-To: {$Tickets{"TOP"}->Id} +Depended-On-By: TOP +Refers-To: TOP Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject} Due: {time + 86400} Content-Type: text/plain @@ -431,6 +431,8 @@ sub Commit { $args{'requestor'} ||= $self->TicketObj->Requestors->MemberEmailAddresses; + $args{'type'} ||= 'ticket'; + my %ticketargs = ( Queue => $args{'queue'}, Subject=> $args{'subject'}, Status => 'new', @@ -452,7 +454,7 @@ sub Commit { foreach my $key (keys(%args)) { - $key =~ /^customfield-(\d+)$/ or next; + $key =~ /^customfield(\d+)$/ or next; $ticketargs{ "CustomField-" . $1 } = $args{$key}; } diff --git a/rt/lib/RT/Action/SendEmail.pm b/rt/lib/RT/Action/SendEmail.pm index dac8fc8e7..659238088 100755 --- a/rt/lib/RT/Action/SendEmail.pm +++ b/rt/lib/RT/Action/SendEmail.pm @@ -129,7 +129,7 @@ sub Commit { $self->SetHeader( 'Cc', join ( ',', @{ $self->{'Cc'} } ) ) if ( $self->{'Cc'} && @{ $self->{'Cc'} } ); $self->SetHeader( 'Bcc', join ( ',', @{ $self->{'Bcc'} } ) ) - if ( $self->{'Cc'} && @{ $self->{'Bcc'} } ); + if ( $self->{'Bcc'} && @{ $self->{'Bcc'} } ); $self->SetHeader('MIME-Version', '1.0'); @@ -266,7 +266,7 @@ sub SendMessage { and ( !$MIMEObj->head->get('To') ) ); if ( $RT::MailCommand eq 'sendmailpipe' ) { eval { - open( MAIL, "|$RT::SendmailPath $RT::SendmailArguments" ); + open( MAIL, "|$RT::SendmailPath $RT::SendmailArguments" ) || die $!; print MAIL $MIMEObj->as_string; close(MAIL); }; diff --git a/rt/lib/RT/Attachment_Overlay.pm b/rt/lib/RT/Attachment_Overlay.pm index d31aa75ad..9086c52f6 100644 --- a/rt/lib/RT/Attachment_Overlay.pm +++ b/rt/lib/RT/Attachment_Overlay.pm @@ -112,8 +112,8 @@ sub Create { #For ease of reference my $Attachment = $args{'Attachment'}; - #if we didn't specify a ticket, we need to bail - if ( $args{'TransactionId'} == 0 ) { + #if we didn't specify a ticket, we need to bail + if ( $args{'TransactionId'} == 0 ) { $RT::Logger->crit( "RT::Attachment->Create couldn't, as you didn't specify a transaction\n" ); return (0); @@ -133,7 +133,9 @@ sub Create { =~ /^.*\bfilename="(.*)"$/ ? $1 : '' }; - if ( $Attachment->parts ) { + # If a message has no bodyhandle, that means that it has subparts (or appears to) + # and we should act accordingly. + unless ( defined $Attachment->bodyhandle ) { $id = $self->SUPER::Create( TransactionId => $args{'TransactionId'}, Parent => 0, @@ -241,6 +243,9 @@ Create an attachment exactly as specified in the named parameters. sub Import { my $self = shift; + my %args = ( ContentEncoding => 'none', + + @_ ); return($self->SUPER::Create(@_)); } @@ -309,11 +314,15 @@ sub OriginalContent { } # Encode::_utf8_on($content); - if (!$enc or $enc eq 'utf8' or $enc eq 'utf-8') { + if (!$enc || $enc eq '' || $enc eq 'utf8' || $enc eq 'utf-8') { # If we somehow fail to do the decode, at least push out the raw bits eval {return( Encode::decode_utf8($content))} || return ($content); } - Encode::from_to($content, 'utf8' => $enc); + + eval { Encode::from_to($content, 'utf8' => $enc);}; + if ($@) { + $RT::Logger->error("Could not convert attachment from assumed utf8 to '$enc' :".$@); + } return $content; } @@ -423,10 +432,13 @@ properly unfolded. =cut sub NiceHeaders { - my $self=shift; - my $hdrs=""; - for (split(/\n/,$self->Headers)) { - $hdrs.="$_\n" if /^(To|From|RT-Send-Cc|Cc|Date|Subject): /i + my $self = shift; + my $hdrs = ""; + my @hdrs = split(/\n/,$self->Headers); + while (my $str = shift @hdrs) { + next unless $str =~ /^(To|From|RT-Send-Cc|Cc|Date|Subject): /i; + $hdrs .= $str . "\n"; + $hdrs .= shift( @hdrs ) . "\n" while ($hdrs[0] =~ /^[ \t]+/); } return $hdrs; } @@ -568,4 +580,13 @@ sub ContentLength { # }}} +# Transactions don't change. by adding this cache congif directiove, we don't lose pathalogically on long tickets. +sub _CacheConfig { + { + 'cache_p' => 1, + 'fast_update_p' => 1, + 'cache_for_sec' => 180, + } +} + 1; diff --git a/rt/lib/RT/Base.pm b/rt/lib/RT/Base.pm index 3b2dcfd3d..47742f8ac 100644 --- a/rt/lib/RT/Base.pm +++ b/rt/lib/RT/Base.pm @@ -23,6 +23,7 @@ # END LICENSE BLOCK package RT::Base; use Carp; +use Scalar::Util; use strict; use vars qw(@EXPORT); @@ -47,12 +48,14 @@ sub CurrentUser { my $self = shift; if (@_) { + $self->{'original_user'} = $self->{'user'}; $self->{'user'} = shift; + Scalar::Util::weaken($self->{'user'}) if (ref($self->{'user'}) && + $self->{'user'} == $self ); } - unless ( $self->{'user'} ) { - $RT::Logger->err( - "$self was created without a CurrentUser\n" . Carp::cluck() ); + unless ( ref( $self->{'user'}) ) { + $RT::Logger->err( "$self was created without a CurrentUser\n" . Carp::cluck() ); return (0); die; } @@ -61,6 +64,16 @@ sub CurrentUser { # }}} +sub OriginalUser { + my $self = shift; + + if (@_) { + $self->{'original_user'} = shift; + Scalar::Util::weaken($self->{'original_user'}) + if (ref($self->{'original_user'}) && $self->{'original_user'} == $self ); + } + return ( $self->{'original_user'} || $self->{'user'} ); +} =item loc LOC_STRING @@ -80,12 +93,14 @@ In english, this would return: sub loc { my $self = shift; - unless ($self->CurrentUser) { + if (my $user = $self->OriginalUser) { + return $user->loc(@_); + } + else { use Carp; Carp::confess("No currentuser"); return ("Critical error:$self has no CurrentUser", $self); } - return($self->CurrentUser->loc(@_)); } eval "require RT::Base_Vendor"; diff --git a/rt/lib/RT/CachedGroupMember_Overlay.pm b/rt/lib/RT/CachedGroupMember_Overlay.pm index f2dc86f0d..8ba7913fa 100644 --- a/rt/lib/RT/CachedGroupMember_Overlay.pm +++ b/rt/lib/RT/CachedGroupMember_Overlay.pm @@ -88,7 +88,7 @@ sub Create { Via => $args{'Via'}, ); unless ($id) { - $RT::Logger->warn( "Couldn't create " + $RT::Logger->warning( "Couldn't create " . $args{'Member'} . " as a cached member of " . $args{'Group'}->Id . " via " @@ -98,7 +98,7 @@ sub Create { if ( $self->__Value('Via') == 0 ) { my ( $vid, $vmsg ) = $self->__Set( Field => 'Via', Value => $id ); unless ($vid) { - $RT::Logger->warn( "Due to a via error, couldn't create " + $RT::Logger->warning( "Due to a via error, couldn't create " . $args{'Member'} . " as a cached member of " . $args{'Group'}->Id . " via " diff --git a/rt/lib/RT/CachedGroupMembers_Overlay.pm b/rt/lib/RT/CachedGroupMembers_Overlay.pm index fd0fd9055..500a54feb 100644 --- a/rt/lib/RT/CachedGroupMembers_Overlay.pm +++ b/rt/lib/RT/CachedGroupMembers_Overlay.pm @@ -136,8 +136,10 @@ sub LimitToGroupsWithMember { my $self = shift; my $member = shift; + + return ($self->Limit( - VALUE => $member, + VALUE => $member || '0', FIELD => 'MemberId', ENTRYAGGREGATOR => 'OR', QUOTEVALUE => 0 diff --git a/rt/lib/RT/CurrentUser.pm b/rt/lib/RT/CurrentUser.pm index 4ca2f9891..7fcc65ce3 100755 --- a/rt/lib/RT/CurrentUser.pm +++ b/rt/lib/RT/CurrentUser.pm @@ -70,7 +70,7 @@ sub _Init { $self->Load($Name); } - $self->CurrentUser($self); + # $self->CurrentUser($self); } # }}} @@ -104,15 +104,13 @@ sub Delete { sub UserObj { my $self = shift; - unless ($self->{'UserObj'}) { use RT::User; - $self->{'UserObj'} = RT::User->new($self); - unless ($self->{'UserObj'}->Load($self->Id)) { + my $user = RT::User->new($self); + + unless ($user->Load($self->Id)) { $RT::Logger->err($self->loc("Couldn't load [_1] from the users database.\n", $self->Id)); } - - } - return ($self->{'UserObj'}); + return ($user); } # }}} @@ -160,6 +158,7 @@ sub _Accessible { Gecos => 'read', RealName => 'read', Password => 'neither', + Lang => 'read', EmailAddress => 'read', Privileged => 'read', IsAdministrator => 'read' @@ -241,6 +240,11 @@ sub Load { if ($identifier !~ /\D/) { $self->SUPER::LoadById($identifier); } + + elsif (UNIVERSAL::isa($identifier,"RT::User")) { + # DWIM if they pass a user in + $self->SUPER::LoadById($identifier->Id); + } else { # This is a bit dangerous, we might get false authen if somebody # uses ambigous userids or real names: @@ -329,6 +333,9 @@ sub LanguageHandle { if ((!defined $self->{'LangHandle'}) || (!UNIVERSAL::can($self->{'LangHandle'}, 'maketext')) || (@_)) { + if ( $self->Lang) { + push @_, $self->Lang; + } $self->{'LangHandle'} = RT::I18N->get_handle(@_); } # Fall back to english. @@ -365,6 +372,19 @@ sub loc_fuzzy { } # }}} + +=head2 CurrentUser + +Return the current currentuser object + +=cut + +sub CurrentUser { + my $self = shift; + return($self); + +} + eval "require RT::CurrentUser_Vendor"; die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Vendor.pm}); eval "require RT::CurrentUser_Local"; diff --git a/rt/lib/RT/CustomField_Overlay.pm b/rt/lib/RT/CustomField_Overlay.pm index 89ef88987..84902a02f 100644 --- a/rt/lib/RT/CustomField_Overlay.pm +++ b/rt/lib/RT/CustomField_Overlay.pm @@ -132,6 +132,12 @@ sub LoadByNameAndQueue { @_, ); + if ($args{'Queue'} =~ /\D/) { + my $QueueObj = RT::Queue->new($self->CurrentUser); + $QueueObj->Load($args{'Queue'}); + $args{'Queue'} = $QueueObj->Id; + } + return ( $self->LoadByCols( Name => $args{'Name'}, Queue => $args{'Queue'} ) ); } diff --git a/rt/lib/RT/EmailParser.pm b/rt/lib/RT/EmailParser.pm index 49f3d5518..bba4d7ec7 100644 --- a/rt/lib/RT/EmailParser.pm +++ b/rt/lib/RT/EmailParser.pm @@ -95,7 +95,7 @@ sub CheckForLoops { #If this instance of RT sent it our, we don't want to take it in my $RTLoop = $head->get("X-RT-Loop-Prevention") || ""; chomp($RTLoop); #remove that newline - if ( $RTLoop =~ /^$RT::rtname/ ) { + if ( $RTLoop =~ /^\Q$RT::rtname\E/o ) { return (1); } @@ -159,28 +159,23 @@ sub ParseMIMEEntityFromSTDIN { # }}} +=head2 ParseMIMEEntityFromScalar $message + +Takes either a scalar or a reference to a scalr which contains a stringified MIME message. +Parses it. + +Returns true if it wins. +Returns false if it loses. + + +=cut sub ParseMIMEEntityFromScalar { my $self = shift; my $message = shift; - # Create a new parser object: - - my $parser = MIME::Parser->new(); - $self->_SetupMIMEParser($parser); - + $self->_DoParse('parse_data', $message); - # TODO: XXX 3.0 we really need to wrap this in an eval { } - unless ( $self->{'entity'} = $parser->parse_data($message) ) { - # Try again, this time without extracting nested messages - $parser->extract_nested_messages(0); - unless ( $self->{'entity'} = $parser->parse_data($message) ) { - $RT::Logger->crit("couldn't parse MIME stream"); - return ( undef); - } - } - $self->_PostProcessNewEntity(); - return (1); } # {{{ ParseMIMEEntityFromFilehandle *FH @@ -195,6 +190,43 @@ sub ParseMIMEEntityFromFileHandle { my $self = shift; my $filehandle = shift; + $self->_DoParse('parse', $filehandle); + +} + +# }}} + +# {{{ ParseMIMEEntityFromFile + +=head2 ParseMIMEEntityFromFile + +Parses a mime entity from a filename passed in as an argument + +=cut + +sub ParseMIMEEntityFromFile { + my $self = shift; + + my $file = shift; + $self->_DoParse('parse_open', $file); +} + +# }}} + +# {{{ _DoParse + +=head2 _DoParse PARSEMETHOD CONTENT + + +A helper for the various parsers to turn around and do the dispatch to the actual parser + +=cut + +sub _DoParse { + my $self = shift; + my $method = shift; + my $file = shift; + # Create a new parser object: my $parser = MIME::Parser->new(); @@ -203,11 +235,11 @@ sub ParseMIMEEntityFromFileHandle { # TODO: XXX 3.0 we really need to wrap this in an eval { } - unless ( $self->{'entity'} = $parser->parse($filehandle) ) { + unless ( $self->{'entity'} = $parser->$method($file) ) { # Try again, this time without extracting nested messages $parser->extract_nested_messages(0); - unless ( $self->{'entity'} = $parser->parse($filehandle) ) { + unless ( $self->{'entity'} = $parser->$method($file) ) { $RT::Logger->crit("couldn't parse MIME stream"); return ( undef); } @@ -218,6 +250,7 @@ sub ParseMIMEEntityFromFileHandle { # }}} + # {{{ _PostProcessNewEntity =head2 _PostProcessNewEntity @@ -250,7 +283,7 @@ sub ParseTicketId { my $Subject = shift; - if ( $Subject =~ s/\[$RT::rtname \#(\d+)\s*\]//i ) { + if ( $Subject =~ s/\[\Q$RT::rtname\E\s+\#(\d+)\s*\]//i ) { my $id = $1; $RT::Logger->debug("Found a ticket ID. It's $id"); return ($id); @@ -762,17 +795,20 @@ sub _SetupMIMEParser { # Set up output directory for files: $parser->output_dir("$AttachmentDir"); + $parser->filer->ignore_filename(1); - #If someone includes a message, don't extract it + + #If someone includes a message, extract it $parser->extract_nested_messages(1); + $parser->extract_uuencode(1); ### default is false + # Set up the prefix for files with auto-generated names: $parser->output_prefix("part"); - # If content length is <= 50000 bytes, store each msg as in-core scalar; - # Else, write to a disk file (the default action): + # do _not_ store each msg as in-core scalar; - $parser->output_to_core(50000); + $parser->output_to_core(0); } # }}} diff --git a/rt/lib/RT/GroupMember_Overlay.pm b/rt/lib/RT/GroupMember_Overlay.pm index 20949f017..9e5bf2189 100644 --- a/rt/lib/RT/GroupMember_Overlay.pm +++ b/rt/lib/RT/GroupMember_Overlay.pm @@ -322,7 +322,7 @@ sub MemberObj { my $self = shift; unless ( defined( $self->{'Member_obj'} ) ) { $self->{'Member_obj'} = RT::Principal->new( $self->CurrentUser ); - $self->{'Member_obj'}->Load( $self->MemberId ); + $self->{'Member_obj'}->Load( $self->MemberId ) if ($self->MemberId); } return ( $self->{'Member_obj'} ); } diff --git a/rt/lib/RT/Group_Overlay.pm b/rt/lib/RT/Group_Overlay.pm index 92150255f..f71fe7f7e 100644 --- a/rt/lib/RT/Group_Overlay.pm +++ b/rt/lib/RT/Group_Overlay.pm @@ -1,3 +1,4 @@ + # BEGIN LICENSE BLOCK # # Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> @@ -327,8 +328,6 @@ sub LoadSystemInternalGroup { my $identifier = shift; $self->LoadByCols( "Domain" => 'SystemInternal', - "Instance" => '', - "Name" => '', "Type" => $identifier ); } @@ -350,7 +349,7 @@ Takes a param hash with 2 parameters: sub LoadTicketRoleGroup { my $self = shift; - my %args = (Ticket => undef, + my %args = (Ticket => '0', Type => undef, @_); $self->LoadByCols( Domain => 'RT::Ticket-Role', @@ -444,7 +443,7 @@ sub _Create { Description => undef, Domain => undef, Type => undef, - Instance => undef, + Instance => '0', InsideTransaction => undef, @_ ); @@ -466,7 +465,7 @@ sub _Create { Description => $args{'Description'}, Type => $args{'Type'}, Domain => $args{'Domain'}, - Instance => $args{'Instance'} + Instance => ($args{'Instance'} || '0') ); my $id = $self->Id; unless ($id) { @@ -798,22 +797,14 @@ sub UserMembersObj { #If we don't have rights, don't include any results # TODO XXX WHY IS THERE NO ACL CHECK HERE? - my $principals = $users->NewAlias('Principals'); - - $users->Join(ALIAS1 => 'main', FIELD1 => 'id', - ALIAS2 => $principals, FIELD2 => 'ObjectId'); - $users->Limit(ALIAS =>$principals, - FIELD => 'PrincipalType', OPERATOR => '=', VALUE => 'User'); - my $cached_members = $users->NewAlias('CachedGroupMembers'); $users->Join(ALIAS1 => $cached_members, FIELD1 => 'MemberId', - ALIAS2 => $principals, FIELD2 => 'id'); + ALIAS2 => $users->PrincipalsAlias, FIELD2 => 'id'); $users->Limit(ALIAS => $cached_members, FIELD => 'GroupId', OPERATOR => '=', VALUE => $self->PrincipalId); - return ( $users); } @@ -1009,6 +1000,10 @@ sub HasMember { return(undef); } + unless ($principal->Id) { + return(undef); + } + my $member_obj = RT::GroupMember->new( $self->CurrentUser ); $member_obj->LoadByCols( MemberId => $principal->id, GroupId => $self->PrincipalId ); diff --git a/rt/lib/RT/Groups_Overlay.pm b/rt/lib/RT/Groups_Overlay.pm index 3d2c660fe..a9ca44c7d 100644 --- a/rt/lib/RT/Groups_Overlay.pm +++ b/rt/lib/RT/Groups_Overlay.pm @@ -80,7 +80,8 @@ Return only SystemInternal Groups, such as "privileged" "unprivileged" and "ever sub LimitToSystemInternalGroups { my $self = shift; $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'SystemInternal'); - $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => ''); + # All system internal groups have the same instance. No reason to limit down further + #$self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '0'); } @@ -98,7 +99,8 @@ Return only UserDefined Groups sub LimitToUserDefinedGroups { my $self = shift; $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined'); - $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => ''); + # All user-defined groups have the same instance. No reason to limit down further + #$self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => ''); } @@ -231,7 +233,7 @@ sub WithRight { my $self = shift; my %args = ( Right => undef, Object => => undef, - IncludeSystemRights => undef, + IncludeSystemRights => 1, IncludeSuperusers => undef, @_ ); @@ -241,11 +243,11 @@ sub WithRight { # {{{ Find only rows where the right granted is the one we're looking up or _possibly_ superuser $self->Limit( ALIAS => $acl, FIELD => 'RightName', - OPERATOR => '=', - VALUE => $args{Right}, + OPERATOR => ($args{Right} ? '=' : 'IS NOT'), + VALUE => $args{Right} || 'NULL', ENTRYAGGREGATOR => 'OR' ); - if ( $args{'IncludeSuperusers'} ) { + if ( $args{'IncludeSuperusers'} and $args{'Right'} ) { $self->Limit( ALIAS => $acl, FIELD => 'RightName', OPERATOR => '=', @@ -254,7 +256,8 @@ sub WithRight { } # }}} - my ($or_check_ticket_roles, $or_check_roles, $or_look_at_object); + my ($or_check_ticket_roles, $or_check_roles); + my $which_object = "$acl.ObjectType = 'RT::System'"; if ( defined $args{'Object'} ) { if ( ref($args{'Object'}) eq 'RT::Ticket' ) { @@ -274,12 +277,18 @@ sub WithRight { " AND main.Type = $acl.PrincipalType AND main.id = $groupprinc.id) "; } - $or_look_at_object = - " OR ($acl.ObjectType = '" . ref($args{'Object'}) . "'" . + if ( $args{'IncludeSystemRights'} ) { + $which_object .= ' OR '; + } + else { + $which_object = ''; + } + $which_object .= + " ($acl.ObjectType = '" . ref($args{'Object'}) . "'" . " AND $acl.ObjectId = " . $args{'Object'}->Id . ") "; } - $self->_AddSubClause( "WhichObject", "($acl.ObjectType = 'RT::System' $or_look_at_object)" ); + $self->_AddSubClause( "WhichObject", "($which_object)" ); $self->_AddSubClause( "WhichGroup", qq{ @@ -294,5 +303,58 @@ sub WithRight { ); } +# {{{ sub LimitToEnabled + +=head2 LimitToEnabled + +Only find items that haven\'t been disabled + +=cut + +sub LimitToEnabled { + my $self = shift; + + my $alias = $self->Join( + TYPE => 'left', + ALIAS1 => 'main', + FIELD1 => 'id', + TABLE2 => 'Principals', + FIELD2 => 'ObjectId' + ); + + $self->Limit( ALIAS => $alias, + FIELD => 'Disabled', + VALUE => '0', + OPERATOR => '=' ); +} +# }}} + +# {{{ sub LimitToDisabled + +=head2 LimitToDeleted + +Only find items that have been deleted. + +=cut + +sub LimitToDeleted { + my $self = shift; + + my $alias = $self->Join( + TYPE => 'left', + ALIAS1 => 'main', + FIELD1 => 'id', + TABLE2 => 'Principals', + FIELD2 => 'ObjectId' + ); + + $self->{'find_disabled_rows'} = 1; + $self->Limit( ALIAS => $alias, + FIELD => 'Disabled', + OPERATOR => '=', + VALUE => '1' + ); +} +# }}} 1; diff --git a/rt/lib/RT/Handle.pm b/rt/lib/RT/Handle.pm index 5cdb65e5b..9b611b903 100644 --- a/rt/lib/RT/Handle.pm +++ b/rt/lib/RT/Handle.pm @@ -60,9 +60,12 @@ Takes nothing. Calls SUPER::Connect with the needed args sub Connect { my $self=shift; -# Unless the database port is a positive integer, we really don't want to pass it. -$self->SUPER::Connect( + if ($RT::DatabaseType eq 'Oracle') { + $ENV{'NLS_LANG'} = ".UTF8"; + } + + $self->SUPER::Connect( User => $RT::DatabaseUser, Password => $RT::DatabasePassword, ); @@ -79,9 +82,11 @@ from the config file. sub BuildDSN { my $self = shift; +# Unless the database port is a positive integer, we really don't want to pass it. $RT::DatabasePort = undef unless (defined $RT::DatabasePort && $RT::DatabasePort =~ /^(\d+)$/); $RT::DatabaseHost = undef unless (defined $RT::DatabaseHost && $RT::DatabaseHost ne ''); + $self->SUPER::BuildDSN(Host => $RT::DatabaseHost, Database => $RT::DatabaseName, Port => $RT::DatabasePort, diff --git a/rt/lib/RT/I18N.pm b/rt/lib/RT/I18N.pm index c013c219e..79c3e8a15 100644 --- a/rt/lib/RT/I18N.pm +++ b/rt/lib/RT/I18N.pm @@ -164,10 +164,14 @@ sub SetMIMEEntityToEncoding { my $charset = _FindOrGuessCharset($entity) or return; # one and only normalization - $charset = 'utf-8' if $charset eq 'utf8'; - $enc = 'utf-8' if $enc eq 'utf8'; + $charset = 'utf-8' if $charset =~ /^utf-?8$/i; + $enc = 'utf-8' if $enc =~ /^utf-?8$/i; - SetMIMEHeadToEncoding($entity->head, $charset => $enc, $preserve_words); + SetMIMEHeadToEncoding( + $entity->head, + _FindOrGuessCharset($entity, 1) => $enc, + $preserve_words + ); my $head = $entity->head; @@ -302,24 +306,26 @@ sub DecodeMIMEWordsToEncoding { # {{{ _FindOrGuessCharset -=head2 _FindOrGuessCharset MIME::Entity +=head2 _FindOrGuessCharset MIME::Entity, $head_only + +When handed a MIME::Entity will first attempt to read what charset the message is encoded in. Failing that, will use Encode::Guess to try to figure it out -When handed a MIME::Entity will first attempt to read what charset the message is encoded in. Failing that, -will use Encode::Guess to try to figure it out +If $head_only is true, only guesses charset for head parts. This is because header's encoding (e.g. filename="...") may be different from that of body's. =cut sub _FindOrGuessCharset { my $entity = shift; + my $head_only = shift; my $head = $entity->head; if ($head->mime_attr("content-type.charset")) { return $head->mime_attr("content-type.charset"); } - if ( $head->mime_type =~ m{^text/}) { + if ( !$head_only and $head->mime_type =~ m{^text/}) { my $body = $entity->bodyhandle or return; - return _GuessCharset( $head->as_string . $body->as_string ); + return _GuessCharset( $body->as_string ); } else { # potentially binary data -- don't guess the body diff --git a/rt/lib/RT/I18N/cs.pm b/rt/lib/RT/I18N/cs.pm index 36e2bc6af..132c3c287 100644 --- a/rt/lib/RT/I18N/cs.pm +++ b/rt/lib/RT/I18N/cs.pm @@ -1,3 +1,26 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK package RT::I18N::cs; # # CZECH TRANSLATORS COMMENTS see Locale::Maketext::TPJ13 diff --git a/rt/lib/RT/I18N/de.po b/rt/lib/RT/I18N/de.po index 3595aad47..3ffc8fbac 100644 --- a/rt/lib/RT/I18N/de.po +++ b/rt/lib/RT/I18N/de.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: RT 2.1.54\n" "POT-Creation-Date: 2002-06-22 06:06+0200\n" "PO-Revision-Date: 2003-02-20 04:47+0200\n" -"Last-Translator: Florian Bischof <flo@fxb.de>\n" +"Last-Translator: Karsten Konrad <karsten.konrad@uni-graz.at>\n" "Language-Team: RT German <rt@fxb.de>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" @@ -183,7 +183,7 @@ msgstr "%1 ist kein %2 dieses Stapels mehr." #: lib/RT/Ticket_Overlay.pm:1570 #. ($principal->Object->Name, $args{'Type'}) msgid "%1 is no longer a %2 for this ticket." -msgstr "%1 ist nicht mehr %2 dieser Anfrage." +msgstr "%1 ist nicht mehr %2 dieser Anfrage." #: lib/RT/Ticket_Overlay.pm:3527 #. ($args{'Value'}, $cf->Name) @@ -194,11 +194,24 @@ msgstr "%1 ist kein Wert des benutzerdefinierten Feldes %2 mehr" msgid "%1 isn't a valid Queue id." msgstr "%1 ist keine gültige Stapel-Id." +#: RTFM +msgid "%1 matches" +msgstr "%1 enthält" + + #: html/Ticket/Elements/ShowBasics:36 #. ($TimeWorked) msgid "%1 min" msgstr "%1 Min" +#: html/RTFM/UpdatedArticles:19 +msgid "%1 most recently updated articles" +msgstr "%1 zuletzt überarbeitete Artikel" + +#: RTFM +msgid "%1 newest articles" +msgstr "%1 neueste Artikel" + #: NOT FOUND IN SOURCE msgid "%1 not shown" msgstr "" @@ -279,10 +292,18 @@ msgstr "(Keine benutzerdefinierten Felder)" msgid "(No members)" msgstr "(Keine Mitglieder)" +#: html/RTFM/NewestArticles:35 +msgid "(no name)" +msgstr "(kein Name)" + #: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32 msgid "(No scrips)" msgstr "(Keine Scrips)" +#: html/RTFM/UpdatedArticles.html:36 +msgid "(no Summary)" +msgstr "keine Zusammenfassung" + #: html/Admin/Elements/EditTemplates:31 msgid "(No templates)" msgstr "(Keine Vorlagen)" @@ -552,6 +573,10 @@ msgstr "Administrative CC" msgid "Advanced Search" msgstr "Erweiterte Suche" +#: RTFM +msgid "Advanced Search Criteria" +msgstr "Erweiterte Suchkriterien" + #: html/Elements/SelectDateRelation:36 msgid "After" msgstr "Nach dem" @@ -564,6 +589,10 @@ msgstr "Alter" msgid "All Custom Fields" msgstr "Alle benutzerdefinierten Felder" +#: html/RTFM/Admin/Classes/index.html:57 +msgid "All Classes" +msgstr "Alle Klassen" + #: html/Admin/Queues/index.html:53 msgid "All Queues" msgstr "Alle Stapel" @@ -572,6 +601,14 @@ msgstr "Alle Stapel" msgid "Always sends a message to the requestors independent of message sender" msgstr "" +#: RTFM +msgid "and is not" +msgstr "und ist nicht" + +#: RTFM +msgid "and not" +msgstr "und nicht" + #: html/Elements/Tabs:58 msgid "Approval" msgstr "Freigabe" @@ -610,10 +647,42 @@ msgstr "Freigeben" msgid "Approver's notes: %1" msgstr "Notizen des Freigebenden: %1" +#: html/RTFM/Admin/CustomFields/UserRights.html:117 +msgid "No Class defined" +msgstr "Keine Klasse definiert" + +#: html/RTFM/Admin/CustomFields/Basics.html:69 +msgid "No CustomField" +msgstr "Kein benutzerdef. Feld" + +#: html/RTFM/Admin/CustomFields/GroupRights.html:73 +msgid "No CustomField defined" +msgstr "Kein benutzerdef. Feld definiert" + #: lib/RT/Date.pm:414 msgid "Apr." msgstr "Apr" +#: RTFM +msgid "Are you sure you want to delete this article?" +msgstr "Sind Sie sicher, dass sie diesen Artikel löschen wollen?" + +#: html/RTFM/Article/delete.html:69 +msgid "Article #%1 deleted" +msgstr "Artikel #%1 gelöscht" + +#: html/RTFM/Article/Display.html:46 +msgid "Article #%1: %2" +msgstr "Artikel #%1: %2" + +#: html/RTFM/Article/Display.html:35 +msgid "Article not found" +msgstr "Artikel wurde nicht gefunden" + +#: RTFM +msgid "Articles" +msgstr "Artikel" + #: html/Elements/SelectSortOrder:35 msgid "Ascending" msgstr "aufsteigend" @@ -739,11 +808,11 @@ msgstr "Kann kein Ticket auf sich selbst verweisen lassen!" #: lib/RT/Ticket_Overlay.pm:2787 msgid "Can't merge into a merged ticket. You should never get this error" -msgstr "Konnte das Ticket nicht in ein vereinigtes Ticket vereinigen. Diesen Fehler solltest du niemals sehen" +msgstr "Konnte das Ticket nicht in ein vereinigtes Ticket vereinigen. Diesen Fehler sollten Sie niemals sehen" #: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674 msgid "Can't specifiy both base and target" -msgstr "Du kannst nicht Basis und Ziel gleichzeitig angeben" +msgstr "Sie können Basis und Ziel nicht gleichzeitig angeben" #: html/autohandler:112 #. ($msg) @@ -774,13 +843,33 @@ msgstr "Kinder" msgid "City" msgstr "Stadt" +#: RTFM +msgid "Class" +msgstr "Klasse" + +#: RTFM +msgid "Class is" +msgstr "Klasse ist" + +#: RTFM +msgid "Class Name" +msgstr "Klassenname" + +#: RTFM +msgid "Classes" +msgstr "Klassen" + +#: share/html/SelfService/Closed.html:27 +msgid "closed" +msgstr "geschlossenen" + #: html/Ticket/Elements/ShowDates:47 msgid "Closed" msgstr "Geschlossen" #: html/SelfService/Elements/Tabs:60 -msgid "Closed requests" -msgstr "Geschossene Tickets" +msgid "Closed tickets" +msgstr "Geschlossene Anfragen" #: NOT FOUND IN SOURCE msgid "Command not understood!\\n" @@ -999,6 +1088,14 @@ msgstr "" msgid "Couldn't load %1 from the users database.\\n" msgstr "Konnte %1 nicht aus der Benutzerdatenbank laden.\\n" +#: html/RTFM/Admin/CustomFields/UserRights.html:121 +msgid "Couldn't load Class %1" +msgstr "Konnte die Klasse %1 nicht laden" + +#: html/RTFM/Admin/CustomFields/GroupRights.html:77 +msgid "Couldn't load CustomField %1" +msgstr "Konnte das benutzerdefinierte Feld %1 nicht laden" + #: NOT FOUND IN SOURCE msgid "Couldn't load RT config file '%1' %2" msgstr "" @@ -1056,6 +1153,10 @@ msgstr "Erstellen" msgid "Create Tickets" msgstr "Erstelle Tickets" +#: RTFM +msgid "Create a Class" +msgstr "Erstelle eine Klasse" + #: html/Admin/Elements/EditCustomField:58 msgid "Create a CustomField" msgstr "Erstelle ein benutzerdefiniertes Feld" @@ -1069,6 +1170,10 @@ msgstr "Erstelle ein benutzerdef. Feld für Stapel %1" msgid "Create a CustomField which applies to all queues" msgstr "Erstelle ein benutzerdef. Feld für alle Stapel" +#: html/RTFM/Article/Create.html:19 +msgid "Create a new article" +msgstr "Erstelle einen neuen Artikel" + #: NOT FOUND IN SOURCE msgid "Create a new Custom Field" msgstr "" @@ -1126,13 +1231,25 @@ msgstr "Erstelle ein Scrip für den Stapel %1" msgid "Create a template" msgstr "Erstelle eine Vorlage" +#: html/SelfService/Create.html:24 +msgid "Create a ticket" +msgstr "Neue Anfrage" + +#: RTFM +msgid "Create an article" +msgstr "Erstelle einen Artikel" + +#: RTFM +msgid "Create an article in class..." +msgstr "Erstelle einen Artikel in der Klasse..." + #: etc/initialdata:130 msgid "Create new tickets based on this scrip's template" msgstr "Erstelle neue Tickets basierend auf der Vorlage dieses Scrips" #: html/SelfService/Create.html:81 msgid "Create ticket" -msgstr "Ticket erstellen" +msgstr "Ãœbermitteln" #: lib/RT/Queue_Overlay.pm:84 msgid "Create tickets in this queue" @@ -1166,11 +1283,19 @@ msgstr "" msgid "Created" msgstr "Angelegt" +#: RTFM +msgid "Created by" +msgstr "Angelegt von" + #: html/Admin/Elements/EditCustomField:71 #. ($CustomFieldObj->Name()) msgid "Created CustomField %1" msgstr "Erstelle ein benutzerdefiniertes Feld %1" +#: RTFM +msgid "Created during" +msgstr "Erstellt zwischen" + #: NOT FOUND IN SOURCE msgid "Created template %1" msgstr "" @@ -1316,7 +1441,7 @@ msgstr "Rechte weitergeben" #: lib/RT/System.pm:63 msgid "Delegate specific rights which have been granted to you." -msgstr "Dir gewährte Rechte weitergeben" +msgstr "Ihnen gewährte Rechte weitergeben" #: lib/RT/System.pm:63 msgid "DelegateRights" @@ -1326,9 +1451,13 @@ msgstr "" msgid "Delegation" msgstr "Rechteweitergabe" -#: NOT FOUND IN SOURCE +#: RTFM msgid "Delete" -msgstr "" +msgstr "Löschen" + +#: html/RTFM/Article/delete.html:73 +msgid "Delete article #%1" +msgstr "Lösche Artikel #%1" #: lib/RT/Queue_Overlay.pm:90 msgid "Delete tickets" @@ -1445,6 +1574,10 @@ msgstr "" msgid "Edit Custom Fields for %1" msgstr "Bearbeite benutzerdefinierte Felder für %1" +#: html/RTFM/Admin/Classes/CustomFields.html:73 +msgid "Edit Custom Fields for Class %1" +msgstr "Bearbeite benutzerdefinierte Felder für Klasse %1" + #: html/Ticket/ModifyLinks.html:36 msgid "Edit Relationships" msgstr "Bearbeite Beziehungen" @@ -1466,6 +1599,10 @@ msgstr "Bearbeite Systemvorlagen" msgid "Edit templates for %1" msgstr "" +#: html/RTFM/Admin/Classes/Modify:79 +msgid "Editing Configuration for Class %1" +msgstr "Bearbeite Konfiguration für die Klasse %1" + #: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117 #. ($QueueObj->Name) #. ($QueueObj->Id) @@ -1517,6 +1654,10 @@ msgstr "E-Mail-Adresse" msgid "EmailEncoding" msgstr "E-Mail-Kodierung" +#: RTFM +msgid "Enabled (Unchecking this box disables this Class)" +msgstr "Aktiviert (Abwählen deaktiviert diese Klasse)" + ### muss das überhaupt übersetzt werden??? #: html/Admin/Elements/EditCustomField:36 msgid "Enabled (Unchecking this box disables this custom field)" @@ -1530,6 +1671,10 @@ msgstr "Aktiviert (Abwählen deaktiviert diese Gruppe)" msgid "Enabled (Unchecking this box disables this queue)" msgstr "Aktiviert (Abwählen deaktiviert diesen Stapel)" +#: RTFM +msgid "Enabled Classes" +msgstr "Aktivierte Klassen" + #: html/Admin/Elements/EditCustomFields:99 msgid "Enabled Custom Fields" msgstr "Aktivierte benutzerdefinierte Felder" @@ -1543,6 +1688,10 @@ msgstr "Aktivierte Stapel" msgid "Enabled status %1" msgstr "Status %1 aktiviert" +#: RTFM +msgid "Enter Articles or URIs to link Articles to. Seperate multiple entries with spaces." +msgstr "Artikel oder URIs getrennt durch Leerzeichen eingeben." + #: lib/RT/CustomField_Overlay.pm:361 msgid "Enter multiple values" msgstr "Mehrere Werte eingeben" @@ -1595,6 +1744,14 @@ msgstr "ExternalContactInfoId" msgid "Extra info" msgstr "Zusatzinformationen" +#: html/RTFM/Article/ExtractIntoClass.html:19 +msgid "Extract article from ticket #%1" +msgstr "Extrahiere Artikel aus Anfrage #%1" + +#: html/RTFM/Article/ExtractFromTicket.html:19 +msgid "Extract article from ticket #%1 into class %2" +msgstr "Extrahiere Artikel aus Anfrage #%1 in die Klasse %2" + #: lib/RT/User_Overlay.pm:302 msgid "Failed to find 'Privileged' users pseudogroup." msgstr "Konnte die Pseudogruppe 'Privileged' nicht finden." @@ -1729,7 +1886,7 @@ msgstr "Gehe zu Seite" #: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25 msgid "Goto ticket" -msgstr "Zeig' Ticket" +msgstr "Zeige Anfrage" #: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78 msgid "Group" @@ -1793,6 +1950,10 @@ msgstr "Hallo %1" msgid "History" msgstr "Historie" +#: html/RTFM/Article/History.html:22 +msgid "History for article #%1" +msgstr "Historie für Artikel #%1" + #: html/Admin/Elements/ModifyUser:68 msgid "HomePhone" msgstr "TelefonZuhause" @@ -1828,7 +1989,7 @@ msgstr "Wenn dieses Werkzeug 'setgid' wäre könnte ein feindlicher lokaler Benu #: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38 msgid "If you've updated anything above, be sure to" -msgstr "Wenn du irgend etwas aktualisiert hast, denke daran hier zu klicken" +msgstr "Wenn Sie irgend etwas aktualisiert haben, denken Sie daran hier zu klicken" #: lib/RT/Interface/Web.pm:860 msgid "Illegal value for %1" @@ -1838,6 +1999,14 @@ msgstr "Unerlaubter Wert für %1" msgid "Immutable field" msgstr "Unveränderbares Feld" +#: RTFM +msgid "in class %1" +msgstr "%1" + +#: RTFM +msgid "Include disabled classes in listing." +msgstr "Zeige auch deaktivierte Klassen an." + #: html/Admin/Elements/EditCustomFields:74 msgid "Include disabled custom fields in listing." msgstr "Zeige auch deaktivierte benutzerdefinierte Felder an." @@ -2157,6 +2326,19 @@ msgstr "Mobil" msgid "MobilePhone" msgstr "Mobiltelefon" +#: RTFM +msgid "Modified" +msgstr "Geändert" + +#: RTFM +msgid "Modify" +msgstr "Ändern" + +#: RTFM +msgid "Modify article #%1" +msgstr "Ändere Artikel #%1" + + #: lib/RT/Queue_Overlay.pm:70 msgid "Modify Access Control List" msgstr "Ändere Zugriffskontrollliste" @@ -2169,6 +2351,10 @@ msgstr "" msgid "Modify Custom Fields which apply to all queues" msgstr "Ändere benutzdefinierte Felder für diesen Stapel" +#: html/RTFM/Admin/CustomFields/GroupRights.html:21 +msgid "Modify group rights for custom field %1" +msgstr "Ändere Gruppenrechte für das benutzerdefinierte Feld %1" + #: lib/RT/Queue_Overlay.pm:73 msgid "Modify Scrip templates for this queue" msgstr "Ändere Scrip-Vorlagen für diesen Stapel" @@ -2374,7 +2560,11 @@ msgstr "Mehrere" #: lib/RT/User_Overlay.pm:179 msgid "Must specify 'Name' attribute" -msgstr "Du musst eine Angabe bei 'Name' machen" +msgstr "Sie müssen eine Angabe bei 'Name' machen" + +#: share/html/SelfService/Elements/MyRequests:32 +msgid "My %1 tickets" +msgstr "Meine %1 Anfragen" #: NOT FOUND IN SOURCE msgid "My Approvals" @@ -2392,6 +2582,10 @@ msgstr "Name" msgid "Name in use" msgstr "Benutzername ist bereits in Gebrauch" +#: RTFM +msgid "Name matches" +msgstr "Name enthält" + #: NOT FOUND IN SOURCE msgid "Need approval from system administrator" msgstr "" @@ -2404,6 +2598,15 @@ msgstr "Niemals" msgid "New" msgstr "Neu" +#: RTFM +msgid "New Article" +msgstr "Neuer Artikel" + +#: RTFM +msgid "New class" +msgstr "Neue Klasse" + + #: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65 msgid "New Password" msgstr "Neues Passwort" @@ -2441,8 +2644,8 @@ msgid "New queue" msgstr "Neuer Stapel" #: html/SelfService/Elements/Tabs:63 -msgid "New request" -msgstr "Neues Ticket" +msgid "New ticket" +msgstr "Neue Anfrage" #: html/Admin/Elements/SelectRights:42 msgid "New rights" @@ -2496,10 +2699,18 @@ msgstr "Spitzname" msgid "Nickname" msgstr "Spitzname" +#: RTFM +msgid "No" +msgstr "Nein" + #: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105 msgid "No CustomField" msgstr "Kein benutzerdefiniertes Feld" +#: html/RTFM/Admin/CustomFields/GrroupRights.html:73 +msgid "No CustomField defined" +msgstr "Kein benutzerdefiniertes Feld definiert" + #: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71 msgid "No Group defined" msgstr "Keine Gruppe definiert" @@ -2777,7 +2988,7 @@ msgid "Open it" msgstr "Öffnen" #: html/SelfService/Elements/Tabs:57 -msgid "Open requests" +msgid "Open tickets" msgstr "Offene Anfragen" #: html/Admin/Users/Prefs.html:41 @@ -2809,6 +3020,10 @@ msgstr "Ursprüngliche Anfrage: #%1" msgid "Over time, priority moves toward" msgstr "Mit der Zeit steigt die Priorität auf" +#: html/RTFM/index.html:19 +msgid "Overview" +msgstr "Ãœbersicht" + #: lib/RT/Queue_Overlay.pm:87 msgid "Own tickets" msgstr "Eigene Anfrage" @@ -3000,6 +3215,10 @@ msgstr "Stapel nicht gefunden" msgid "Queues" msgstr "Stapel" +#: RTFM +msgid "Quick search" +msgstr "Schnellsuche" + #: html/Elements/Login:34 #. ($RT::VERSION) msgid "RT %1" @@ -3047,9 +3266,13 @@ msgstr "RT Fehler" msgid "RT Received mail (%1) from itself." msgstr "" +#: html/RTFM/Error:36 +msgid "RTFM Error" +msgstr "RTFM Fehler" + #: html/SelfService/Closed.html:25 -msgid "RT Self Service / Closed Tickets" -msgstr "RT Selbstbedienung / Geschlossene Anfragen" +msgid "Closed Tickets" +msgstr "Geschlossene Anfragen" #: html/index.html:25 html/index.html:28 msgid "RT at a glance" @@ -3082,13 +3305,17 @@ msgstr "" #: NOT FOUND IN SOURCE msgid "RT has proccessed your commands" -msgstr "RT hat Deine Befehle verarbeitet" +msgstr "RT hat Ihre Befehle verarbeitet" #: html/Elements/Login:83 #. ('2003') msgid "RT is © Copyright 1996-%1 Jesse Vincent <jesse@bestpractical.com>. It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>" msgstr "RT © Copyright 1996-%1 Jesse Vincent <jesse@bestpractical.com>. Vertrieben unter der <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>" +#: share/html/SelfService/Elements/Tabs:35 +msgid "RT Self Service" +msgstr "RT Selbstbedienung" + #: NOT FOUND IN SOURCE msgid "RT thinks this message may be a bounce" msgstr "" @@ -3318,6 +3545,10 @@ msgstr "" msgid "Search for approvals" msgstr "Suche nach Freigaben" +#: html/RTFM/Article/Search.html:19 +msgid "Search for articles" +msgstr "Artikel suchen" + #: bin/rt-crontool:188 msgid "Security:" msgstr "Sicherheit:" @@ -3326,6 +3557,14 @@ msgstr "Sicherheit:" msgid "SeeQueue" msgstr "" +#: RTFM +msgid "Select a Class" +msgstr "Wähle eine Klasse aus" + +#: RTFM +msgid "Select a Custom Fields" +msgstr "Wähle ein benutzerdefiniertes Feld aus" + #: html/Admin/Groups/index.html:40 msgid "Select a group" msgstr "Wähle eine Gruppe aus" @@ -3338,6 +3577,10 @@ msgstr "" msgid "Select a user" msgstr "Wähle einen Benutzer aus" +#: RTFM +msgid "Select class" +msgstr "Wähle eine Klasse" + #: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36 msgid "Select custom field" msgstr "Wähle ein benutzerdef. Feld" @@ -3364,7 +3607,7 @@ msgstr "Wähle ein Scrip" #: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55 msgid "Select template" -msgstr "Wähle ein Template" +msgstr "Wähle eine Vorlage" #: html/Admin/Elements/UserTabs:49 msgid "Select user" @@ -3422,10 +3665,18 @@ msgstr "Schicke eine Mail an den Inhaber" msgid "Sep." msgstr "Sep" +#: RTFM +msgid "Seperate multiple URLs with spaces" +msgstr "Mehrere URLs getrennt durch Leerzeichen eingeben" + #: NOT FOUND IN SOURCE msgid "Show Results" msgstr "" +#: RTFM +msgid "Show advanced search options..." +msgstr "Zeige erweiterte Suchoptionen an..." + #: html/Approvals/Elements/PendingMyApproval:44 msgid "Show approved requests" msgstr "Zeige freigegebene Anfragen" @@ -3511,10 +3762,23 @@ msgstr "Sortierschlüssel" msgid "Sort results by" msgstr "Sortiere Ergebnisse nach" +#: RTFM +msgid "Sort Order" +msgstr "Sortierreihenfolge" + #: html/Admin/Elements/AddCustomFieldValue:25 msgid "SortOrder" msgstr "Sortierreihenfolge" +#: RTFM +msgid "Summary" +msgstr "Zusammenfassung" + +#: RTFM +msgid "Summary matches" +msgstr "Zusammenfassung enthält" + + #: NOT FOUND IN SOURCE msgid "Stalled" msgstr "" @@ -3587,6 +3851,10 @@ msgid "Submit" msgstr "Ãœbermitteln" #: NOT FOUND IN SOURCE +msgid "Submit Query" +msgstr "Suchen" + +#: NOT FOUND IN SOURCE msgid "Submit Workflow" msgstr "" @@ -3933,6 +4201,10 @@ msgstr "Arbeitszeit" msgid "Time left" msgstr "Ãœbrige Zeit" +#: RTFM +msgid "till" +msgstr "und" + #: html/Elements/Footer:36 msgid "Time to display" msgstr "Benötigte Zeit" @@ -3990,6 +4262,10 @@ msgstr "Di" msgid "Type" msgstr "Typ" +#: html/RTFM/Article/delete.html:59 +msgid "Unable to load article" +msgstr "Artikel kann nicht geladen werden" + #: lib/RT/ScripCondition_Overlay.pm:104 msgid "Unimplemented" msgstr "Nicht implementiert" @@ -4082,6 +4358,10 @@ msgstr "Aktualisierungstyp war weder Korrespondenz noch Kommentar." msgid "Updated" msgstr "Aktualisiert" +#: html/RTFM/Article/ExtractFromTicket.html:26 +msgid "Use the dropdown menus to select which transactions you want to extract into a new RTFM article" +msgstr "Ãœber die Auswahllisten kann bestimmt werden welche Transaktionen in den neuen RTFM Artikel extrahiert werden" + #: NOT FOUND IN SOURCE msgid "User %1 %2: %3\\n" msgstr "" @@ -4223,6 +4503,14 @@ msgstr "Immer wenn ein neuer Kommentar eingeht" msgid "Whenever correspondence comes in" msgstr "Immer wenn neue Korrespondenz eingeht" +#: html/RTFM/Article/Elements/ShowSearchCriteria:64 +msgid "Which refer to" +msgstr "Beziehen sich auf" + +#: html/RTFM/Article/Elements/ShowSearchCriteria:64 +msgid "Which are referred to by " +msgstr "Bezogen von" + #: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52 msgid "Work" msgstr "Arbeit" @@ -4235,17 +4523,21 @@ msgstr "Arbeitstelefon" msgid "Worked" msgstr "Arbeitszeit" +#: RTFM +msgid "Yes" +msgstr "Ja" + #: lib/RT/Ticket_Overlay.pm:3056 msgid "You already own this ticket" -msgstr "Du besitzt diese Anfrage bereits" +msgstr "Sie besitzen diese Anfrage bereits" #: html/autohandler:121 msgid "You are not an authorized user" -msgstr "Du bist kein authorisierter Benutzer" +msgstr "Sie sind kein authorisierter Benutzer" #: lib/RT/Ticket_Overlay.pm:2930 msgid "You can only reassign tickets that you own or that are unowned" -msgstr "Du kannst nur Anfragen ohne Inhaber zuweisen" +msgstr "Sie können nur Anfragen ohne Inhaber zuweisen" #: NOT FOUND IN SOURCE msgid "You don't have permission to view that ticket.\\n" @@ -4254,23 +4546,23 @@ msgstr "" #: docs/design_docs/string-extraction-guide.txt:47 #. ($num, $queue) msgid "You found %1 tickets in queue %2" -msgstr "Du hast %1 Anfragen in Stapel %2 gefunden" +msgstr "Sie haben %1 Anfragen in Stapel %2 gefunden" #: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25 msgid "You have been logged out of RT." -msgstr "Du wurdest von RT abgemeldet." +msgstr "Sie wurden von RT abgemeldet." #: html/SelfService/Display.html:134 msgid "You have no permission to create tickets in that queue." -msgstr "Du hast kein Recht, Anfragen in diesen Stapel anzulegen." +msgstr "Sie haben kein Recht, Anfragen in diesen Stapel anzulegen." #: lib/RT/Ticket_Overlay.pm:1895 msgid "You may not create requests in that queue." -msgstr "Du darfst in diesem Stapel keine Anfragen erstellen" +msgstr "Sie dürfen in diesem Stapel keine Anfragen erstellen" #: html/NoAuth/Logout.html:36 msgid "You're welcome to login again" -msgstr "Du kannst dich gerne wieder anmelden" +msgstr "Sie können sich gerne wieder anmelden" #: html/SelfService/Elements/MyRequests:25 #. ($friendly_status) @@ -4283,11 +4575,11 @@ msgstr "" #: etc/initialdata:429 etc/upgrade/2.1.71:146 msgid "Your request has been approved by %1. Other approvals may still be pending." -msgstr "Deine Anfrage wurde von %1 freigegeben. Andere Freigaben können noch ausstehen." +msgstr "Ihre Anfrage wurde von %1 freigegeben. Andere Freigaben können noch ausstehen." #: etc/initialdata:463 etc/upgrade/2.1.71:180 msgid "Your request has been approved." -msgstr "Deine Anfrage wurde freigegeben." +msgstr "Ihre Anfrage wurde freigegeben." #: NOT FOUND IN SOURCE msgid "Your request was rejected" @@ -4295,11 +4587,11 @@ msgstr "" #: etc/initialdata:384 etc/upgrade/2.1.71:101 msgid "Your request was rejected." -msgstr "Deine Anfrage wurde abgewiesen" +msgstr "Ihre Anfrage wurde abgewiesen" #: html/autohandler:136 html/autohandler:142 msgid "Your username or password is incorrect" -msgstr "Dein Benutzername oder Passwort ist falsch" +msgstr "Ihr Benutzername oder Passwort ist falsch" #: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96 msgid "Zip" diff --git a/rt/lib/RT/I18N/it.po b/rt/lib/RT/I18N/it.po new file mode 100644 index 000000000..55a478ba2 --- /dev/null +++ b/rt/lib/RT/I18N/it.po @@ -0,0 +1,6175 @@ +# translation of it.po to +# translation of it.po to +# translation of it.po to +# translation of it.po to +# translation of it.po to +# translation of it.po to +# Copyright (c) 2002 Jesse Vincent <jesse@bestpractical.com> +# root <root@delpreterh>, 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: it\n" +"POT-Creation-Date: 2002-05-02 11:36+0800\n" +"PO-Revision-Date: 2003-07-21 22:20+0200\n" +"Last-Translator: root <root@delpreterh>\n" +"Language-Team: <en@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0.1\n" + +#: html/Elements/MyRequests:27 +#: html/Elements/MyTickets:27 +msgid "#" +msgstr "n°" + +#. ($QueueObj->id) +#: html/Admin/Queues/Scrip.html:54 +msgid "#%1" +msgstr "n°%1" + +#. ($Ticket->Id, $Ticket->Subject) +#. ($Ticket->id, $Ticket->Subject) +#. ($ticket->Id, $ticket->Subject) +#. ($link->BaseObj->Id, $link->BaseObj->Subject) +#: html/Approvals/Elements/Approve:26 +#: html/Approvals/Elements/ShowDependency:49 +#: html/SelfService/Display.html:24 +#: html/Ticket/Display.html:25 +#: html/Ticket/Display.html:29 +msgid "#%1: %2" +msgstr "n°%1: %2" + +#. ($s, $time_unit) +#: lib/RT/Date.pm:336 +msgid "%1 %2" +msgstr "%1 %2" + +#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'}) +#: lib/RT/Tickets_Overlay.pm:770 +msgid "%1 %2 %3" +msgstr "%1 %2 %3" + +#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900)) +#: lib/RT/Date.pm:372 +msgid "%1 %2 %3 %4:%5:%6 %7" +msgstr "%1 %2 %3 %4:%5:%6 %7" + +#. ($cf->Name, $new_value->Content) +#. ($field, $self->NewValue) +#. ($self->Field, $principal->Object->Name) +#: lib/RT/Ticket_Overlay.pm:3504 +#: lib/RT/Transaction_Overlay.pm:556 +#: lib/RT/Transaction_Overlay.pm:598 +msgid "%1 %2 added" +msgstr "%1 %2 aggiunto" + +#. ($s, $time_unit) +#: lib/RT/Date.pm:333 +msgid "%1 %2 ago" +msgstr "%1 %2 fa" + +#. ($cf->Name, $old_value, $new_value->Content) +#. ($field, $self->OldValue, $self->NewValue) +#: lib/RT/Ticket_Overlay.pm:3510 +#: lib/RT/Transaction_Overlay.pm:563 +msgid "%1 %2 changed to %3" +msgstr "%1 %2 cambiato in %3" + +#. ($cf->Name, $old_value) +#. ($field, $self->OldValue) +#. ($self->Field, $principal->Object->Name) +#: lib/RT/Ticket_Overlay.pm:3507 +#: lib/RT/Transaction_Overlay.pm:559 +#: lib/RT/Transaction_Overlay.pm:604 +msgid "%1 %2 deleted" +msgstr "%1 %2 eliminato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 %2 of group %3" +msgstr "%1 %2 del gruppo %3" + +#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name)) +#: html/Admin/Elements/EditScrips:43 +#: html/Admin/Elements/ListGlobalScrips:27 +msgid "%1 %2 with template %3" +msgstr "%1 %2 con il modello %3" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 (%2) %3 this ticket\\n" +msgstr "%1 (%2) %3 questo ticket\\n" + +#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage() )) +#: html/Search/Listing.html:56 +msgid "%1 - %2 shown" +msgstr "Tickets da %1 a %2" + +#. ("--search-argument", "--search") +#. ("--condition-argument", "--condition") +#. ("--action-argument", "--action") +#: bin/rt-crontool:168 +#: bin/rt-crontool:175 +#: bin/rt-crontool:181 +msgid "%1 - An argument to pass to %2" +msgstr "%1 - Un parametro da passare a %2" + +#. ("--verbose") +#: bin/rt-crontool:184 +msgid "%1 - Output status updates to STDOUT" +msgstr "%1 - Lo stato dell'output è stato aggiornato su STDOUT" + +#. ("--action") +#: bin/rt-crontool:178 +msgid "%1 - Specify the action module you want to use" +msgstr "%1 - Specificare l'azione che si vuole eseguire" + +#. ("--condition") +#: bin/rt-crontool:172 +msgid "%1 - Specify the condition module you want to use" +msgstr "%1 - Specificare la condizione che si vuole utilizzare" + +#. ("--search") +#: bin/rt-crontool:165 +msgid "%1 - Specify the search module you want to use" +msgstr "%1 - Specificare la ricerca che si vuole utilizzare" + +#. ($self->Id) +#: lib/RT/ScripAction_Overlay.pm:121 +msgid "%1 ScripAction loaded" +msgstr "%1 ScripAction caricato" + +#. ($args{'Value'}, $cf->Name) +#: lib/RT/Ticket_Overlay.pm:3537 +msgid "%1 added as a value for %2" +msgstr "%1 aggiunto(i) come valore di %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 aliases require a TicketId to work on" +msgstr "gli alias %1 necessitano di un TicketId su cui lavorare" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 aliases require a TicketId to work on " +msgstr "gli alias %1 necessitano di un TicketId su cui lavorare" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 aliases require a TicketId to work on (from %2) %3" +msgstr "gli alias %1 necessitano di un TicketId per funzionare con (dopo %2) %3" + +#. ($args{'Base'}) +#. ($args{'Target'}) +#: lib/RT/Link_Overlay.pm:116 +#: lib/RT/Link_Overlay.pm:123 +msgid "%1 appears to be a local object, but can't be found in the database" +msgstr "%1 sembra essere un oggetto locale, ma è introvabile nel database" + +#. ($self->BriefDescription , $self->CreatorObj->Name) +#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name) +#: html/Ticket/Elements/ShowDates:51 +#: lib/RT/Transaction_Overlay.pm:480 +msgid "%1 by %2" +msgstr "%1 per %2" + +#. ($self->Field , ( $self->OldValue || $no_value ) , $self->NewValue) +#. ($self->Field , $q1->Name , $q2->Name) +#. ($self->Field, $t2->AsString, $t1->AsString) +#. ($self->Field, $self->OldValue, $self->NewValue) +#: lib/RT/Transaction_Overlay.pm:534 +#: lib/RT/Transaction_Overlay.pm:623 +#: lib/RT/Transaction_Overlay.pm:632 +#: lib/RT/Transaction_Overlay.pm:635 +msgid "%1 changed from %2 to %3" +msgstr "%1 cambiato(1) da %2 a %3" + +#: lib/RT/Interface/Web.pm:890 +msgid "%1 could not be set to %2." +msgstr "%1 non può essere impostato a %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 couldn't init a transaction (%2)\\n" +msgstr "%1 non ha potuto iniziare una transazione (%2)\\n" + +#. ($self) +#: lib/RT/Ticket_Overlay.pm:2816 +msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent." +msgstr "%1 non ho potuto mettere lo stato a risolto. Il database RT può essere inconsistente." + +#. ($rows) +#: html/Elements/MyTickets:24 +msgid "%1 highest priority tickets I own..." +msgstr "I miei %1 tickets a più alta priorità che possiedo..." + +#. ($rows) +#: html/Elements/MyRequests:24 +msgid "%1 highest priority tickets I requested..." +msgstr "I miei %1 tickets a più alta priorità che ho richiesto..." + +#. ($0) +#: bin/rt-crontool:160 +msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron." +msgstr "%1 è uno strumento per lavorare sui tickets da uno schedulatore esterno, come cron" + +#. ($principal->Object->Name, $args{'Type'}) +#: lib/RT/Queue_Overlay.pm:742 +msgid "%1 is no longer a %2 for this queue." +msgstr "%1 non è più un %2 per questa coda." + +#. ($principal->Object->Name, $args{'Type'}) +#: lib/RT/Ticket_Overlay.pm:1569 +msgid "%1 is no longer a %2 for this ticket." +msgstr "%1 non è più un %2 per questo ticket." + +#. ($args{'Value'}, $cf->Name) +#: lib/RT/Ticket_Overlay.pm:3593 +msgid "%1 is no longer a value for custom field %2" +msgstr "%1 non è più un valore per il campo personalizzato %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 isn't a valid Queue id." +msgstr "%1 non è un identificativo di coda valido" + +#. ($TimeWorked) +#: html/Ticket/Elements/ShowBasics:35 +msgid "%1 min" +msgstr "%1 min" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 not shown" +msgstr "%1 non mostrato" + +#. (loc($ObjectType =~ /^RT::(.*)$/)) +#: html/User/Elements/DelegateRights:75 +msgid "%1 rights" +msgstr "Diritti di %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 succeeded\\n" +msgstr "%1 riuscito\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 type unknown for $MessageId" +msgstr "Tipo %1 sconosciuto per $MessageId" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 type unknown for %2" +msgstr "Tipo %1 sconosciuto per %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 was created without a CurrentUser\\n" +msgstr "%1 è stato creato senza un CurrentUser\\n" + +#. (ref $self) +#: lib/RT/Action/ResolveMembers.pm:41 +msgid "%1 will resolve all members of a resolved group ticket." +msgstr "%1 risolverà tutti i membri di un gruppo di ticket risolto." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request." +msgstr "%1 bloccherà una BASE [locale] se dipende o è membro di una richeista linkata." + +#. ($self) +#: lib/RT/Transaction_Overlay.pm:432 +msgid "%1: no attachment specified" +msgstr "%1: nessun allegato specificato" + +#. ($size) +#: html/Ticket/Elements/ShowTransaction:101 +msgid "%1b" +msgstr "%1b" + +#. (int($size/102.4)/10) +#: html/Ticket/Elements/ShowTransaction:98 +msgid "%1k" +msgstr "%1k" + +#. ($args{'Status'}) +#: lib/RT/Ticket_Overlay.pm:1139 +msgid "'%1' is an invalid value for status" +msgstr "'%1' è uno stato non valido" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "'%1' not a recognized action. " +msgstr "'%1' non è un'azione conosciuta. " + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "(Check box to delete group member)" +msgstr "(Spunta la casella per cancellare il membro di un gruppo)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "(Check box to delete scrip)" +msgstr "(Spunta la casella per cancellare uno scrip)" + +#: html/Admin/Elements/EditCustomFieldValues:24 +#: html/Admin/Elements/EditQueueWatchers:28 +#: html/Admin/Elements/EditScrips:34 +#: html/Admin/Elements/EditTemplates:35 +#: html/Admin/Groups/Members.html:51 +#: html/Ticket/Elements/EditLinks:32 +#: html/Ticket/Elements/EditPeople:45 +#: html/User/Groups/Members.html:54 +msgid "(Check box to delete)" +msgstr "(Spunta la casella per cancellare)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "(Check boxes to delete)" +msgstr "(Spunta la casella per cancellare)" + +#: html/Ticket/Create.html:177 +msgid "(Enter ticket ids or URLs, seperated with spaces)" +msgstr "(Inserire il numero di tickets o gli URL, separati da spazi)" + +#. ($RT::CorrespondAddress) +#. ($RT::CommentAddress) +#: html/Admin/Queues/Modify.html:53 +#: html/Admin/Queues/Modify.html:59 +msgid "(If left blank, will default to %1" +msgstr "Se lasciato vuoto, valore di default : %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "(No Value)" +msgstr "(Nessun Valore)" + +#: html/Admin/Elements/EditCustomFields:32 +#: html/Admin/Elements/ListGlobalCustomFields:31 +msgid "(No custom fields)" +msgstr "Non ci sono campi personalizzati" + +#: html/Admin/Groups/Members.html:49 +#: html/User/Groups/Members.html:52 +msgid "(No members)" +msgstr "(Nessun membro)" + +#: html/Admin/Elements/EditScrips:31 +#: html/Admin/Elements/ListGlobalScrips:31 +msgid "(No scrips)" +msgstr "(Nessuno Scrip)" + +#: html/Admin/Elements/EditTemplates:30 +msgid "(No templates)" +msgstr "Nessun modello" + +#: html/Ticket/Update.html:84 +msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)" +msgstr "(Invia per copia nascosta questo aggiornamento ad una lista di indirizzi email separati da virgole. Ciò <b>non cambierà </b> i destinatari dei successivi aggiornamenti.)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)" +msgstr "(Invia per copia nascosta questo aggiornamento ad una lista di indirizzi email separati da virgole. Ciò <b>non cambierà </b> i destinatari dei successivi aggiornamenti.)" + +#: html/Ticket/Create.html:78 +msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)" +msgstr "(Invia una copia di questo aggiornamento ad una lista di indirizzi email amministrativi separati da virgole. Queste persone <b>riceveranno</b> i successivi aggiornamenti.)" + +#: html/Ticket/Update.html:80 +msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)" +msgstr "(Invia una copia di questo aggiornamento ad una lista di indirizzi email separati da virgole. Ciò <b>non cambierà </b> i destinatari dei successivi aggiornamenti.)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)" +msgstr "(Invia una copia di questo aggiornamento ad una lista di indirizzi email separati da virgole. Ciò <b>non cambierà </b> i destinatari dei successivi aggiornamenti.)" + +#: html/Ticket/Create.html:68 +msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)" +msgstr "(Invia una copia di questo aggiornamento ad una lista di indirizzi email separati da virgole. Queste persone <b>riceveranno</b> i successivi aggiornamenti.)" + +#: html/Admin/Groups/index.html:32 +#: html/User/Groups/index.html:32 +msgid "(empty)" +msgstr "(vuoto)" + +#: html/Admin/Users/index.html:38 +msgid "(no name listed)" +msgstr "(nessun nome)" + +#: html/Elements/MyRequests:42 +#: html/Elements/MyTickets:44 +msgid "(no subject)" +msgstr "(nessun oggetto)" + +#: html/Admin/Elements/SelectRights:47 +#: html/Elements/SelectCustomFieldValue:29 +#: html/Ticket/Elements/EditCustomField:58 +#: html/Ticket/Elements/ShowCustomFields:35 +#: lib/RT/Transaction_Overlay.pm:533 +msgid "(no value)" +msgstr "(nessun valore)" + +#: html/Ticket/Elements/EditLinks:115 +msgid "(only one ticket)" +msgstr "(solo un ticket)" + +#: html/Elements/MyRequests:51 +#: html/Elements/MyTickets:54 +msgid "(pending approval)" +msgstr "(in attesa di approvazione)" + +#: html/Elements/MyRequests:53 +#: html/Elements/MyTickets:56 +msgid "(pending other tickets)" +msgstr "(in attea di altri tickets)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "(requestor's group)" +msgstr "(gruppo del richiedente)" + +#: html/Admin/Users/Modify.html:49 +msgid "(required)" +msgstr "(richiesto)" + +#: html/Ticket/Elements/ShowTransaction:104 +msgid "(untitled)" +msgstr "(senza titolo)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "25 highest priority tickets I own..." +msgstr "I miei 25 tickets che devo trattare con priorità più alta..." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "25 highest priority tickets I requested..." +msgstr "I miei 25 tickets che hor ichiesto con priorità più alta..." + +#: html/Ticket/Elements/ShowBasics:31 +msgid "<% $Ticket->Status%>" +msgstr "<% $Ticket->Status%>" + +#: html/Elements/SelectTicketTypes:26 +msgid "<% $_ %>" +msgstr "" + +#. ($m->scomp('/Elements/SelectNewTicketQueue')) +#: docs/design_docs/string-extraction-guide.txt:54 +#: html/Elements/CreateTicket:25 +msgid "<input type=\"submit\" value=\"New ticket in\"> %1" +msgstr "<input type=\"submit\" value=\"Crea un ticket in\"> %1" + +#: etc/initialdata:203 +msgid "A blank template" +msgstr "Un modello vuoto" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "ACE Deleted" +msgstr "ACE Eliminata" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "ACE Loaded" +msgstr "ACE Caricata" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "ACE could not be deleted" +msgstr "l'ACE non è stato possibile elimanarla" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "ACE could not be found" +msgstr "l'ACE non è stato possibile trovarla" + +#: lib/RT/ACE_Overlay.pm:156 +#: lib/RT/Principal_Overlay.pm:180 +msgid "ACE not found" +msgstr "ACE non trovata" + +#: lib/RT/ACE_Overlay.pm:830 +msgid "ACEs can only be created and deleted." +msgstr "Le ACE possono essere solo create e cancellate." + +#: bin/rt-commit-handler:754 +msgid "Aborting to avoid unintended ticket modifications.\\n" +msgstr "Interruzione per evitare modifiche di ticket involontarie.\\n" + +#: html/User/Elements/Tabs:31 +msgid "About me" +msgstr "A proposito" + +#: html/Admin/Users/Modify.html:79 +msgid "Access control" +msgstr "Controllo di Accesso" + +#: html/Admin/Elements/EditScrip:56 +msgid "Action" +msgstr "Azione" + +#. ($args{'ScripAction'}) +#: lib/RT/Scrip_Overlay.pm:146 +msgid "Action %1 not found" +msgstr "Azione %1 non trovata" + +#: bin/rt-crontool:122 +msgid "Action committed." +msgstr "Azione eseguita." + +#: bin/rt-crontool:118 +msgid "Action prepared..." +msgstr "Azione preparata..." + +#: html/Search/Bulk.html:91 +msgid "Add AdminCc" +msgstr "Aggiungi AdminCC" + +#: html/Search/Bulk.html:89 +msgid "Add Cc" +msgstr "Aggiungi CC" + +#: html/Ticket/Create.html:113 +#: html/Ticket/Update.html:99 +msgid "Add More Files" +msgstr "Aggiungi Altri Files" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Add Next State" +msgstr "Aggiungi lo Stato Sucessivo" + +#: html/Search/Bulk.html:87 +msgid "Add Requestor" +msgstr "Aggiungi il Richiedente" + +#: html/Admin/Elements/AddCustomFieldValue:24 +msgid "Add Value" +msgstr "Aggiungi un Valore" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Add a keyword selection to this queue" +msgstr "Aggiungi una selezione di parole chiave a questa coda" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Add a new a global scrip" +msgstr "Aggiungi un nuovo scrip globale" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Add a scrip to this queue" +msgstr "Aggiungi uno scrip a questa coda" + +#: html/Admin/Global/Scrip.html:54 +msgid "Add a scrip which will apply to all queues" +msgstr "Aggiungi uno scrip da applicare a tutte le code" + +#: html/Search/Bulk.html:117 +msgid "Add comments or replies to selected tickets" +msgstr "Agiungere commenti o repliche ai tickets selezionati" + +#: html/Admin/Groups/Members.html:41 +#: html/User/Groups/Members.html:38 +msgid "Add members" +msgstr "Aggiungi membri" + +#: html/Admin/Queues/People.html:65 +#: html/Ticket/Elements/AddWatchers:27 +msgid "Add new watchers" +msgstr "Aggiungi nuovi osservatori" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "AddNextState" +msgstr "AggiungereStatoSuccessivo" + +#. ($args{'Type'}) +#: lib/RT/Queue_Overlay.pm:642 +msgid "Added principal as a %1 for this queue" +msgstr "Aggiunto gruppo/utente come %1 per questa coda" + +#. ($self->loc($args{'Type'})) +#: lib/RT/Ticket_Overlay.pm:1453 +msgid "Added principal as a %1 for this ticket" +msgstr "Aggiunto gruppo/utente come %1 per questo ticket" + +#: html/Admin/Elements/ModifyUser:75 +#: html/Admin/Users/Modify.html:121 +#: html/User/Prefs.html:87 +msgid "Address1" +msgstr "Inidirizzo1" + +#: html/Admin/Elements/ModifyUser:77 +#: html/Admin/Users/Modify.html:126 +#: html/User/Prefs.html:89 +msgid "Address2" +msgstr "Indirizzo2" + +#: html/Ticket/Create.html:73 +msgid "Admin Cc" +msgstr "Admin Cc" + +#: etc/initialdata:280 +msgid "Admin Comment" +msgstr "Commento Amministrativo" + +#: etc/initialdata:259 +msgid "Admin Correspondence" +msgstr "Corrispondenza Amministrativa " + +#: html/Admin/Queues/index.html:24 +#: html/Admin/Queues/index.html:27 +msgid "Admin queues" +msgstr "Amministra le code" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Admin users" +msgstr "Amministra gli Utenti" + +#: html/Admin/Global/index.html:25 +#: html/Admin/Global/index.html:27 +msgid "Admin/Global configuration" +msgstr "configurazione Amministratore/Globale" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Admin/Groups" +msgstr "Amministra/Gruppi" + +#: html/Admin/Queues/Modify.html:24 +#: html/Admin/Queues/Modify.html:28 +msgid "Admin/Queue/Basics" +msgstr "Amministra/Code/Base" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "AdminAllPersonalGroups" +msgstr "AmministraTuttiIGruppiPersonali" + +#: etc/initialdata:56 +#: html/Ticket/Elements/ShowPeople:38 +#: html/Ticket/Update.html:49 +#: lib/RT/ACE_Overlay.pm:88 +msgid "AdminCc" +msgstr "AdminCc" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "AdminComment" +msgstr "CommentoAmministratore" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "AdminCorrespondence" +msgstr "CorrispondenzaAmministratore" + +#: lib/RT/Queue_Overlay.pm:71 +msgid "AdminCustomFields" +msgstr "AmministraCampiPersonalizzati" + +#: lib/RT/Group_Overlay.pm:145 +msgid "AdminGroup" +msgstr "AmministraGruppi" + +#: lib/RT/Group_Overlay.pm:147 +msgid "AdminGroupMembership" +msgstr "AmministraAppartenenzaGruppi" + +#: lib/RT/System.pm:58 +msgid "AdminOwnPersonalGroups" +msgstr "AmministraPropriGruppiPersonali" + +#: lib/RT/Queue_Overlay.pm:67 +msgid "AdminQueue" +msgstr "AmministraCode" + +#: lib/RT/System.pm:59 +msgid "AdminUsers" +msgstr "AmministraUtenti" + +#: html/Admin/Queues/People.html:47 +#: html/Ticket/Elements/EditPeople:53 +msgid "Administrative Cc" +msgstr "Cc Amministrativa" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Admins" +msgstr "Amministratori" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Advanced Search" +msgstr "Ricerca avanzata" + +#: html/Elements/SelectDateRelation:35 +msgid "After" +msgstr "Dopo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Age" +msgstr "Età " + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Alias" +msgstr "" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Alias for" +msgstr "Alias per" + +#: html/Admin/Elements/EditCustomFields:95 +msgid "All Custom Fields" +msgstr "Tutti i campi personalizzati" + +#: html/Admin/Queues/index.html:52 +msgid "All Queues" +msgstr "Tutte le code" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Always sends a message to the requestors independent of message sender" +msgstr "Invia sempre un messaggio al richiedente inipendentemente dal mittente" + +#: html/Elements/Tabs:55 +msgid "Approval" +msgstr "Approvazione" + +#. ($Ticket->Id, $Ticket->Subject) +#. ($ticket->id, $msg) +#. ($link->BaseObj->Id, $link->BaseObj->Subject) +#: html/Approvals/Display.html:45 +#: html/Approvals/Elements/ShowDependency:41 +#: html/Approvals/index.html:64 +msgid "Approval #%1: %2" +msgstr "Approvazione n°%1: %2" + +#. ($ticket->Id) +#: html/Approvals/index.html:53 +msgid "Approval #%1: Notes not recorded due to a system error" +msgstr "Approvazione n°%1: Note non registrate a causa di un errore di sistema" + +#. ($ticket->Id) +#: html/Approvals/index.html:51 +msgid "Approval #%1: Notes recorded" +msgstr "Approvazione n°%1: Note registrate" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Approval Details" +msgstr "Dettagli dell'approvazione" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Approval diagram" +msgstr "Diagramma dell'approvazione" + +#: html/Approvals/Elements/Approve:43 +msgid "Approve" +msgstr "Approvare" + +#: etc/initialdata:437 +#: etc/upgrade/2.1.71:148 +msgid "Approver's notes: %1" +msgstr "Note dell'approvatore: %1" + +#: lib/RT/Date.pm:413 +msgid "Apr." +msgstr "Apr." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "April" +msgstr "Aprile" + +#: html/Elements/SelectSortOrder:34 +msgid "Ascending" +msgstr "Ascendente" + +#: html/Search/Bulk.html:126 +#: html/SelfService/Update.html:32 +#: html/Ticket/ModifyAll.html:82 +#: html/Ticket/Update.html:99 +msgid "Attach" +msgstr "Allegato" + +#: html/SelfService/Create.html:64 +#: html/Ticket/Create.html:109 +msgid "Attach file" +msgstr "Allegare un file" + +#: html/Ticket/Create.html:97 +#: html/Ticket/Update.html:88 +msgid "Attached file" +msgstr "File allegato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Attachment '%1' could not be loaded" +msgstr "L'allegato '%1' non può essere caricato" + +#: lib/RT/Transaction_Overlay.pm:440 +msgid "Attachment created" +msgstr "Allegato creato" + +#: lib/RT/Tickets_Overlay.pm:1188 +msgid "Attachment filename" +msgstr "Nome file dell'allegato" + +#: html/Ticket/Elements/ShowAttachments:25 +msgid "Attachments" +msgstr "Allegati" + +#: lib/RT/Date.pm:417 +msgid "Aug." +msgstr "Ago." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "August" +msgstr "Agosto" + +#: html/Admin/Elements/ModifyUser:65 +msgid "AuthSystem" +msgstr "AuthSystem" + +#: etc/initialdata:206 +msgid "Autoreply" +msgstr "RispostaAutomatica" + +#: etc/initialdata:72 +msgid "Autoreply To Requestors" +msgstr "Risposta automatica ai richiedenti" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "AutoreplyToRequestors" +msgstr "RispostaAutomaticaAiRichiedenti" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Bad PGP Signature: %1\\n" +msgstr "Firma PGP non valida: %1\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Bad attachment id. Couldn't find attachment '%1'\\n" +msgstr "Id di allegato errato. Impossibile trovare l'allegato '%1'\\n" + +#. ($val) +#: bin/rt-commit-handler:826 +msgid "Bad data in %1" +msgstr "Dati incorretti in %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Bad transaction number for attachment. %1 should be %2\\n" +msgstr "Numero di transazione incorretto per l'allegato. %1 dovrebbe essere %2\\n" + +#: html/Admin/Elements/GroupTabs:38 +#: html/Admin/Elements/QueueTabs:38 +#: html/Admin/Elements/UserTabs:37 +#: html/Ticket/Elements/Tabs:89 +#: html/User/Elements/GroupTabs:37 +msgid "Basics" +msgstr "Essenziale" + +#: html/Ticket/Update.html:82 +msgid "Bcc" +msgstr "Bcc" + +#: html/Admin/Elements/EditScrip:87 +#: html/Admin/Global/GroupRights.html:84 +#: html/Admin/Global/Template.html:45 +#: html/Admin/Global/UserRights.html:53 +#: html/Admin/Groups/GroupRights.html:72 +#: html/Admin/Groups/Members.html:80 +#: html/Admin/Groups/Modify.html:55 +#: html/Admin/Groups/UserRights.html:54 +#: html/Admin/Queues/GroupRights.html:84 +#: html/Admin/Queues/Template.html:44 +#: html/Admin/Queues/UserRights.html:53 +#: html/User/Groups/Modify.html:55 +msgid "Be sure to save your changes" +msgstr "Assicurarsi di salvare le modifiche" + +#: html/Elements/SelectDateRelation:33 +#: lib/RT/CurrentUser.pm:319 +msgid "Before" +msgstr "Prima" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Begin Approval" +msgstr "Inizio dell'approvazione" + +#: etc/initialdata:202 +msgid "Blank" +msgstr "Vuoto" + +#: html/Search/Listing.html:78 +msgid "Bookmarkable URL for this search" +msgstr "URL predefinito per questa ricerca" + +#: html/Ticket/Elements/ShowHistory:38 +#: html/Ticket/Elements/ShowHistory:44 +msgid "Brief headers" +msgstr "Intestazioni brevi" + +#: html/Search/Bulk.html:24 +#: html/Search/Bulk.html:25 +msgid "Bulk ticket update" +msgstr "Modifica di massa dei tickets" + +#: lib/RT/User_Overlay.pm:1351 +msgid "Can not modify system users" +msgstr "Gli utenti di sistema non possono essere modificati" + +#: lib/RT/Queue_Overlay.pm:66 +msgid "Can this principal see this queue" +msgstr "Il gruppo/utente può vedere questa coda" + +#: lib/RT/CustomField_Overlay.pm:205 +msgid "Can't add a custom field value without a name" +msgstr "Impossibile aggiungere un valore di campo personalizzato senza un nome" + +#: lib/RT/Link_Overlay.pm:131 +msgid "Can't link a ticket to itself" +msgstr "Non è possibile collegare un ticket a se stesso" + +#: lib/RT/Ticket_Overlay.pm:2793 +msgid "Can't merge into a merged ticket. You should never get this error" +msgstr "Impossibile unire un ticket ad un ticket già unito. Non dovrebbe mai comparire questo errore" + +#: lib/RT/Ticket_Overlay.pm:2611 +#: lib/RT/Ticket_Overlay.pm:2680 +msgid "Can't specifiy both base and target" +msgstr "Impossibile specificare sia la base che il target" + +#. ($msg) +#: html/autohandler:98 +msgid "Cannot create user: %1" +msgstr "Impossibile creare l'utente: %1" + +#: etc/initialdata:50 +#: html/Admin/Queues/People.html:43 +#: html/SelfService/Create.html:48 +#: html/Ticket/Create.html:63 +#: html/Ticket/Elements/EditPeople:50 +#: html/Ticket/Elements/ShowPeople:34 +#: html/Ticket/Update.html:44 +#: html/Ticket/Update.html:77 +#: lib/RT/ACE_Overlay.pm:87 +msgid "Cc" +msgstr "Cc" + +#: html/SelfService/Prefs.html:30 +msgid "Change password" +msgstr "Cambiare la passwrd" + +#: html/Ticket/Create.html:100 +#: html/Ticket/Update.html:91 +msgid "Check box to delete" +msgstr "Spunta la casella per eliminare" + +#: html/Admin/Elements/SelectRights:30 +msgid "Check box to revoke right" +msgstr "Spunta la casella per revocare i diritti" + +#: html/Ticket/Create.html:182 +#: html/Ticket/Elements/EditLinks:130 +#: html/Ticket/Elements/EditLinks:68 +#: html/Ticket/Elements/ShowLinks:56 +msgid "Children" +msgstr "Figli" + +#: html/Admin/Elements/ModifyUser:79 +#: html/Admin/Users/Modify.html:131 +#: html/User/Prefs.html:91 +msgid "City" +msgstr "Città " + +#: html/Ticket/Elements/ShowDates:46 +msgid "Closed" +msgstr "Chiuso" + +#: html/SelfService/Closed.html:24 +msgid "Closed Tickets" +msgstr "Tickets Chiusi" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Closed requests" +msgstr "Richieste chiuse" + +#: html/SelfService/Elements/Tabs:44 +msgid "Closed tickets" +msgstr "Tickets chiusi" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Code" +msgstr "" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Command not understood!\\n" +msgstr "Comando non riconosciuto! \\n" + +#: html/Ticket/Elements/ShowTransaction:178 +#: html/Ticket/Elements/Tabs:152 +msgid "Comment" +msgstr "Commento" + +#: html/Admin/Elements/ModifyQueue:44 +#: html/Admin/Queues/Modify.html:57 +msgid "Comment Address" +msgstr "Inidirizzo di Commento" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Comment not recorded" +msgstr "Commento non registrato" + +#: lib/RT/Queue_Overlay.pm:85 +msgid "Comment on tickets" +msgstr "Commento sui tickets" + +#: lib/RT/Queue_Overlay.pm:85 +msgid "CommentOnTicket" +msgstr "CommentoSuiTickets" + +#: html/Admin/Elements/ModifyUser:34 +msgid "Comments" +msgstr "Commenti" + +#: html/Ticket/ModifyAll.html:69 +#: html/Ticket/Update.html:69 +msgid "Comments (Not sent to requestors)" +msgstr "Commenti (Non inviati ai richiedenti)" + +#: html/Search/Bulk.html:121 +msgid "Comments (not sent to requestors)" +msgstr "Commenti (non inviati ai richiedenti)" + +#. ($name) +#: html/Elements/ViewUser:26 +msgid "Comments about %1" +msgstr "Commenti su %1" + +#: html/Admin/Users/Modify.html:184 +#: html/Ticket/Elements/ShowRequestor:43 +msgid "Comments about this user" +msgstr "Commenti su questo utente" + +#: lib/RT/Transaction_Overlay.pm:542 +msgid "Comments added" +msgstr "Commenti aggiunti" + +#: lib/RT/Action/Generic.pm:139 +msgid "Commit Stubbed" +msgstr "tr(Commit Stubbed)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Compile Restrictions" +msgstr "Restrizioni di compilazione" + +#: html/Admin/Elements/EditScrip:40 +msgid "Condition" +msgstr "Condizione" + +#: bin/rt-crontool:108 +msgid "Condition matches..." +msgstr "La condizione soddisfa..." + +#: lib/RT/Scrip_Overlay.pm:159 +msgid "Condition not found" +msgstr "Condizione non trovata" + +#: html/Elements/Tabs:49 +msgid "Configuration" +msgstr "Configurazione" + +#: html/SelfService/Prefs.html:32 +msgid "Confirm" +msgstr "Confermare" + +#: html/Admin/Elements/ModifyUser:59 +msgid "ContactInfoSystem" +msgstr "ContactInfoSystem" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Contacted date '%1' could not be parsed" +msgstr "La data di contatto '%1' non può essere analizzata" + +#: html/Admin/Elements/ModifyTemplate:43 +#: html/Ticket/ModifyAll.html:86 +msgid "Content" +msgstr "Contenuto" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Coould not create group" +msgstr "Non è stato possibile creare il gruppo" + +#: etc/initialdata:271 +msgid "Correspondence" +msgstr "Corrispondenza" + +#: html/Admin/Elements/ModifyQueue:38 +#: html/Admin/Queues/Modify.html:50 +msgid "Correspondence Address" +msgstr "Inidirizzo di corrispondenza" + +#: lib/RT/Transaction_Overlay.pm:538 +msgid "Correspondence added" +msgstr "Corrispondenza aggiunta" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Correspondence not recorded" +msgstr "Corrispondenza non registrata" + +#: lib/RT/Ticket_Overlay.pm:3524 +msgid "Could not add new custom field value for ticket. " +msgstr "Impossibile aggiungere un nuovo valore di campo personalizzato a questo ticket. " + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Could not add new custom field value for ticket. %1 " +msgstr "Il valore di campo personalizzato non è stato possibile aggiungerlo. %1" + +#: lib/RT/Ticket_Overlay.pm:3030 +#: lib/RT/Ticket_Overlay.pm:3038 +#: lib/RT/Ticket_Overlay.pm:3054 +msgid "Could not change owner. " +msgstr "Impossibile cambiare il proprietario. " + +#. ($msg) +#: html/Admin/Elements/EditCustomField:84 +#: html/Admin/Elements/EditCustomFields:165 +msgid "Could not create CustomField" +msgstr "Impossibile creare il campo personalizzato" + +#: html/User/Groups/Modify.html:76 +#: lib/RT/Group_Overlay.pm:473 +#: lib/RT/Group_Overlay.pm:480 +msgid "Could not create group" +msgstr "Impossibile creare il gruppo" + +#. ($msg) +#: html/Admin/Global/Template.html:74 +#: html/Admin/Queues/Template.html:71 +msgid "Could not create template: %1" +msgstr "Impossibile creare il modello : %1" + +#: lib/RT/Ticket_Overlay.pm:1072 +#: lib/RT/Ticket_Overlay.pm:333 +msgid "Could not create ticket. Queue not set" +msgstr "Impossibile creare il ticket. Queue non impostata" + +#: lib/RT/User_Overlay.pm:207 +#: lib/RT/User_Overlay.pm:219 +#: lib/RT/User_Overlay.pm:237 +#: lib/RT/User_Overlay.pm:421 +msgid "Could not create user" +msgstr "Impossibile creare l'utente" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Could not create watcher for requestor" +msgstr "Impossibile creare l'osservatore per il richiedente" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Could not find a ticket with id %1" +msgstr "Impossibile trovare il ticket numero %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Could not find group %1." +msgstr "Impossibile trovare il gruppo %1." + +#: lib/RT/Queue_Overlay.pm:620 +#: lib/RT/Ticket_Overlay.pm:1421 +msgid "Could not find or create that user" +msgstr "Impossibile trovare o creare questo utente" + +#: lib/RT/Queue_Overlay.pm:681 +#: lib/RT/Ticket_Overlay.pm:1500 +msgid "Could not find that principal" +msgstr "Impossibile trovare questo gruppo/utente" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Could not find user %1." +msgstr "Impossibile trovare l'utente %1." + +#: html/Admin/Groups/Members.html:87 +#: html/User/Groups/Members.html:89 +#: html/User/Groups/Modify.html:81 +msgid "Could not load group" +msgstr "Impossibile caricare questo gruppo" + +#. ($args{'Type'}) +#: lib/RT/Queue_Overlay.pm:640 +msgid "Could not make that principal a %1 for this queue" +msgstr "Impossibile rendere questo gruppo/utente un %1 per questa coda" + +#. ($self->loc($args{'Type'})) +#: lib/RT/Ticket_Overlay.pm:1442 +msgid "Could not make that principal a %1 for this ticket" +msgstr "Impossibile rendere questo gruppo/utente un %1 per questo ticket" + +#. ($args{'Type'}) +#: lib/RT/Queue_Overlay.pm:739 +msgid "Could not remove that principal as a %1 for this queue" +msgstr "Impossibile eliminare questo gruppo/utente come un %1 per questa coda" + +#. ($args{'Type'}) +#: lib/RT/Ticket_Overlay.pm:1558 +msgid "Could not remove that principal as a %1 for this ticket" +msgstr "Impossibile eliminare questo gruppo/utente come un %1 per questo ticket" + +#: lib/RT/Group_Overlay.pm:984 +msgid "Couldn't add member to group" +msgstr "Impossibile aggiungere un membro a questo gruppo" + +#. ($Msg) +#: lib/RT/Ticket_Overlay.pm:3534 +#: lib/RT/Ticket_Overlay.pm:3590 +msgid "Couldn't create a transaction: %1" +msgstr "Impossibile creare una transazione : %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't figure out what to do from gpg's reply\\n" +msgstr "Impossibile capire che cosa fare con questa risposta gpg\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't find group\\n" +msgstr "Gruppo introvabile\\n" + +#: lib/RT/Interface/Web.pm:899 +msgid "Couldn't find row" +msgstr "Riga introvabile" + +#: lib/RT/Group_Overlay.pm:958 +msgid "Couldn't find that principal" +msgstr "Gruppo/utente introvabile" + +#: lib/RT/CustomField_Overlay.pm:239 +msgid "Couldn't find that value" +msgstr "Valore introvabile" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't find that watcher" +msgstr "Osservatore introvabile" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't find user\\n" +msgstr "Utente introvabile\\n" + +#. ($self->Id) +#: lib/RT/CurrentUser.pm:111 +msgid "Couldn't load %1 from the users database.\\n" +msgstr "Impossibile caricare %1 dal database degli utenti.\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't load KeywordSelects." +msgstr "KeywordSelects non è stato possibile caricarlo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't load RT config file '%1' %2" +msgstr "Impossibile caricare il file di configurazione RT '%1' %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't load Scrips." +msgstr "Impossibile caricare gli Scrips" + +#. ($id) +#: html/Admin/Groups/GroupRights.html:87 +#: html/Admin/Groups/UserRights.html:74 +msgid "Couldn't load group %1" +msgstr "Impossibile caricare il gruppo %1" + +#: lib/RT/Link_Overlay.pm:174 +#: lib/RT/Link_Overlay.pm:183 +#: lib/RT/Link_Overlay.pm:210 +msgid "Couldn't load link" +msgstr "Impossibile caricare il link" + +#. ($id) +#: html/Admin/Elements/EditCustomFields:146 +#: html/Admin/Queues/People.html:120 +msgid "Couldn't load queue" +msgstr "Impossibile caricare la coda" + +#. ($id) +#: html/Admin/Queues/GroupRights.html:99 +#: html/Admin/Queues/UserRights.html:71 +msgid "Couldn't load queue %1" +msgstr "Impossibile caricare la coda %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't load scrip" +msgstr "Impossibile caricare lo Scrip" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Couldn't load template" +msgstr "Impossibile caricare il modello" + +#. ($id) +#: html/Admin/Users/Prefs.html:78 +msgid "Couldn't load that user (%1)" +msgstr "Impossibile caricare questo utente (%1)" + +#. ($id) +#: html/SelfService/Display.html:108 +msgid "Couldn't load ticket '%1'" +msgstr "Impossibile caricare il ticket '%1'" + +#: html/Admin/Elements/ModifyUser:85 +#: html/Admin/Users/Modify.html:148 +#: html/User/Prefs.html:97 +msgid "Country" +msgstr "Stato" + +#: html/Admin/Elements/CreateUserCalled:25 +#: html/Ticket/Create.html:134 +#: html/Ticket/Create.html:194 +msgid "Create" +msgstr "Crea" + +#: etc/initialdata:128 +msgid "Create Tickets" +msgstr "Crea tickets" + +#: html/Admin/Elements/EditCustomField:74 +msgid "Create a CustomField" +msgstr "Crea un campo Personalizzato" + +#. ($QueueObj->Name()) +#: html/Admin/Queues/CustomField.html:47 +msgid "Create a CustomField for queue %1" +msgstr "Crea un campo Custom per la coda %1" + +#: html/Admin/Global/CustomField.html:47 +msgid "Create a CustomField which applies to all queues" +msgstr "Crea un campo Personalizzato valido per tutte le code" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create a new Custom Field" +msgstr "Crea un nuovo campo Personalizzato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create a new global scrip" +msgstr "Crea un nuovo scrip globale" + +#: html/Admin/Groups/Modify.html:66 +#: html/Admin/Groups/Modify.html:92 +msgid "Create a new group" +msgstr "Crea un nuovo gruppo" + +#: html/User/Groups/Modify.html:66 +#: html/User/Groups/Modify.html:91 +msgid "Create a new personal group" +msgstr "Crea un nuovo gruppo personale" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create a new queue" +msgstr "Crea una nuova coda" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create a new scrip" +msgstr "Crea un nuovo scrip" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create a new template" +msgstr "Crea un nuovo modello" + +#: html/Ticket/Create.html:24 +#: html/Ticket/Create.html:27 +#: html/Ticket/Create.html:35 +msgid "Create a new ticket" +msgstr "Crea un nuovo ticket" + +#: html/Admin/Users/Modify.html:213 +#: html/Admin/Users/Modify.html:240 +msgid "Create a new user" +msgstr "Crea un nuovo utente" + +#: html/Admin/Queues/Modify.html:102 +msgid "Create a queue" +msgstr "Crea una coda" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create a queue called" +msgstr "Crea una nuova coda chiamata" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create a request" +msgstr "Crea una richiesta" + +#. ($QueueObj->Name) +#: html/Admin/Queues/Scrip.html:58 +msgid "Create a scrip for queue %1" +msgstr "Crea uno scrip per la coda %1" + +#: html/Admin/Global/Template.html:68 +#: html/Admin/Queues/Template.html:64 +msgid "Create a template" +msgstr "Crea un modello" + +#: html/SelfService/Create.html:24 +msgid "Create a ticket" +msgstr "Crea un ticket" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create failed: %1 / %2 / %3 " +msgstr "Eccezione durante la creazione: %1 / %2 / %3" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create failed: %1/%2/%3" +msgstr "Eccezione durante la creazione: %1/%2/%3" + +#: etc/initialdata:130 +msgid "Create new tickets based on this scrip's template" +msgstr "Creare nuovi tickets basati su questo modello di scrip" + +#: html/SelfService/Create.html:77 +msgid "Create ticket" +msgstr "Crea un ticket" + +#: lib/RT/Queue_Overlay.pm:83 +msgid "Create tickets in this queue" +msgstr "Crea dei tickets in questa coda" + +#: lib/RT/Queue_Overlay.pm:71 +msgid "Create, delete and modify custom fields" +msgstr "Crea, elimina e modifica campi personalizzati" + +#: lib/RT/Queue_Overlay.pm:67 +msgid "Create, delete and modify queues" +msgstr "Crea, elimina e modifica le code" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Create, delete and modify the members of any user's personal groups" +msgstr "Crea, elimina e modifica i membri dei gruppi personali di un qualunque utente" + +#: lib/RT/System.pm:58 +msgid "Create, delete and modify the members of personal groups" +msgstr "Crea, elimina e modifica i membri dei gruppi personali " + +#: lib/RT/System.pm:59 +msgid "Create, delete and modify users" +msgstr "Crea, elimina e modifica gli utenti" + +#: lib/RT/Queue_Overlay.pm:83 +msgid "CreateTicket" +msgstr "CreaTicket" + +#: html/Elements/SelectDateType:25 +#: html/Ticket/Elements/ShowDates:26 +#: lib/RT/Ticket_Overlay.pm:1166 +msgid "Created" +msgstr "Creato" + +#. ($CustomFieldObj->Name()) +#: html/Admin/Elements/EditCustomField:87 +msgid "Created CustomField %1" +msgstr "Campo Personalizzato %1 creato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Created template %1" +msgstr "Modello %1 creato" + +#: html/Ticket/Elements/EditLinks:27 +msgid "Current Relationships" +msgstr "Relazioni attuali" + +#: html/Admin/Elements/EditScrips:29 +msgid "Current Scrips" +msgstr "Scrips attuali" + +#: html/Admin/Groups/Members.html:38 +#: html/User/Groups/Members.html:41 +msgid "Current members" +msgstr "Membri attuali" + +#: html/Admin/Elements/SelectRights:28 +msgid "Current rights" +msgstr "Diritti attuali" + +#: html/Search/Listing.html:70 +msgid "Current search criteria" +msgstr "Criterio di ricerca corrente" + +#: html/Admin/Queues/People.html:40 +#: html/Ticket/Elements/EditPeople:44 +msgid "Current watchers" +msgstr "Osservatori attuali" + +#. ($CustomField) +#: html/Admin/Global/CustomField.html:54 +msgid "Custom Field #%1" +msgstr "Campo Personalizzato n°%1" + +#: html/Admin/Elements/QueueTabs:52 +#: html/Admin/Elements/SystemTabs:39 +#: html/Admin/Global/index.html:49 +#: html/Ticket/Elements/ShowSummary:35 +msgid "Custom Fields" +msgstr "Campi Personalizzati" + +#: html/Admin/Elements/EditScrip:72 +msgid "Custom action cleanup code" +msgstr "Programma di pulizia dell'azione personalizzata" + +#: html/Admin/Elements/EditScrip:64 +msgid "Custom action preparation code" +msgstr "Programma di preparazione dell'azione personalizzata" + +#: html/Admin/Elements/EditScrip:48 +msgid "Custom condition" +msgstr "Condizione personalizzata" + +#. ($CF->Name , $args{OPERATOR} , $args{VALUE}) +#: lib/RT/Tickets_Overlay.pm:1617 +msgid "Custom field %1 %2 %3" +msgstr "Campi personalizzati %1 %2 %3" + +#. ($CF->Name) +#: lib/RT/Tickets_Overlay.pm:1612 +msgid "Custom field %1 has a value." +msgstr "Il campo personalizzato %1 ha un valore" + +#. ($CF->Name) +#: lib/RT/Tickets_Overlay.pm:1609 +msgid "Custom field %1 has no value." +msgstr "Il campo personalizzato %1 non ha valore" + +#. ($args{'Field'}) +#: lib/RT/Ticket_Overlay.pm:3426 +msgid "Custom field %1 not found" +msgstr "Il campo personalizzato %1 è introvabile" + +#: html/Admin/Elements/EditCustomFields:196 +msgid "Custom field deleted" +msgstr "Campo Personalizzato cancellato" + +#: lib/RT/Ticket_Overlay.pm:3576 +msgid "Custom field not found" +msgstr "Il campo personalizzato è introvabile" + +#. ($args{'Content'}, $self->Name) +#: lib/RT/CustomField_Overlay.pm:349 +msgid "Custom field value %1 could not be found for custom field %2" +msgstr "Il valore del campo personalizzato %1 non è stato possibile trovarlo per il campo personalizzato %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Custom field value changed from %1 to %2" +msgstr "Il valore del campo personalizzato è stato modificato da %1 à %2" + +#: lib/RT/CustomField_Overlay.pm:249 +msgid "Custom field value could not be deleted" +msgstr "Il valore del campo personalizzato non è stato possibile eliminarlo" + +#: lib/RT/CustomField_Overlay.pm:355 +msgid "Custom field value could not be found" +msgstr "Il valore del campo personalizzato non è stato possibile trovarlo" + +#: lib/RT/CustomField_Overlay.pm:247 +#: lib/RT/CustomField_Overlay.pm:357 +msgid "Custom field value deleted" +msgstr "Il valore del vampo personalizzato è stato eliminato" + +#: lib/RT/Transaction_Overlay.pm:547 +msgid "CustomField" +msgstr "CampoPersonalizzato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Data error" +msgstr "Errore nei dati" + +#: html/SelfService/Display.html:38 +#: html/Ticket/Create.html:160 +#: html/Ticket/Elements/ShowSummary:54 +#: html/Ticket/Elements/Tabs:92 +#: html/Ticket/ModifyAll.html:43 +msgid "Dates" +msgstr "Date" + +#: lib/RT/Date.pm:421 +msgid "Dec." +msgstr "Dic." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "December" +msgstr "Dicembre" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Default Autoresponse Template" +msgstr "Modello di default per la risposta automatica" + +#: etc/initialdata:207 +msgid "Default Autoresponse template" +msgstr "Modello di default per la risposta automatica" + +#: etc/initialdata:281 +msgid "Default admin comment template" +msgstr "Modello di default per il commento amministrativo" + +#: etc/initialdata:260 +msgid "Default admin correspondence template" +msgstr "Modello di default per la corrispondenza amministrativa" + +#: etc/initialdata:272 +msgid "Default correspondence template" +msgstr "Modello di default per la corrispondenza" + +#: etc/initialdata:238 +msgid "Default transaction template" +msgstr "Modello di default per la transazione" + +#. ($type, $self->Field, $self->OldValue, $self->NewValue) +#: lib/RT/Transaction_Overlay.pm:642 +msgid "Default: %1/%2 changed from %3 to %4" +msgstr "Defaut: %1/%2 modificato da %3 à %4" + +#: html/User/Delegation.html:24 +#: html/User/Delegation.html:27 +msgid "Delegate rights" +msgstr "Delega i diritti" + +#: lib/RT/System.pm:62 +msgid "Delegate specific rights which have been granted to you." +msgstr "Delega dei diritti specifici che ti sono stati accordati" + +#: lib/RT/System.pm:62 +msgid "DelegateRights" +msgstr "DelegaDiritti" + +#: html/User/Elements/Tabs:37 +msgid "Delegation" +msgstr "Delega" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Delete" +msgstr "Elimina" + +#: lib/RT/Queue_Overlay.pm:89 +msgid "Delete tickets" +msgstr "Elimina dei tickets" + +#: lib/RT/Queue_Overlay.pm:89 +msgid "DeleteTicket" +msgstr "EliminaTicket" + +#: lib/RT/Transaction_Overlay.pm:186 +msgid "Deleting this object could break referential integrity" +msgstr "Eliminare quest'oggetto può interrompere l'integrità referenziale" + +#: lib/RT/Queue_Overlay.pm:291 +msgid "Deleting this object would break referential integrity" +msgstr "Eliminare quest'oggetto interomperà l'integrità referenziale" + +#: lib/RT/User_Overlay.pm:437 +msgid "Deleting this object would violate referential integrity" +msgstr "Eliminare quest'oggetto violerà l'integrità referenziale" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Deleting this object would violate referential integrity." +msgstr "Eliminare quest'oggetto violerà l'integrità referenziale" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Deleting this object would violate referential integrity. That's bad." +msgstr "Eliminare quest'oggetto violerà l'integrità referenziale. Malissimo!" + +#: html/Approvals/Elements/Approve:44 +msgid "Deny" +msgstr "Negare" + +#: html/Ticket/Create.html:180 +#: html/Ticket/Elements/EditLinks:122 +#: html/Ticket/Elements/EditLinks:46 +#: html/Ticket/Elements/ShowDependencies:31 +#: html/Ticket/Elements/ShowLinks:36 +msgid "Depended on by" +msgstr "Usato come dipendenza da" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Dependencies: \\n" +msgstr "Dipendenze : \\n" + +#: html/Elements/SelectLinkType:26 +#: html/Ticket/Create.html:179 +#: html/Ticket/Elements/EditLinks:118 +#: html/Ticket/Elements/EditLinks:35 +#: html/Ticket/Elements/ShowDependencies:24 +#: html/Ticket/Elements/ShowLinks:26 +msgid "Depends on" +msgstr "Dipende da" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "DependsOn" +msgstr "DipendeDa" + +#: html/Elements/SelectSortOrder:34 +msgid "Descending" +msgstr "Discendente" + +#: html/SelfService/Create.html:72 +#: html/Ticket/Create.html:118 +msgid "Describe the issue below" +msgstr "Descrivere il problema qui sotto" + +#: html/Admin/Elements/AddCustomFieldValue:35 +#: html/Admin/Elements/EditCustomField:38 +#: html/Admin/Elements/EditScrip:33 +#: html/Admin/Elements/ModifyQueue:35 +#: html/Admin/Elements/ModifyTemplate:35 +#: html/Admin/Groups/Modify.html:48 +#: html/Admin/Queues/Modify.html:47 +#: html/Elements/SelectGroups:26 +#: html/User/Groups/Modify.html:48 +msgid "Description" +msgstr "Descrizione" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Details" +msgstr "Dettagli" + +#: html/Ticket/Elements/Tabs:84 +msgid "Display" +msgstr "Mostra" + +#: lib/RT/Queue_Overlay.pm:68 +msgid "Display Access Control List" +msgstr "Mostra la Lista Controllo Accessi" + +#: lib/RT/Queue_Overlay.pm:74 +msgid "Display Scrip templates for this queue" +msgstr "Mostra i modelli di Scrips per questa coda" + +#: lib/RT/Queue_Overlay.pm:77 +msgid "Display Scrips for this queue" +msgstr "Mostra gli Scrips per questa coda" + +#: html/Ticket/Elements/ShowHistory:34 +msgid "Display mode" +msgstr "Modalità visualizzazione" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Display ticket #%1" +msgstr "Mostra il ticket n°%1" + +#: lib/RT/System.pm:53 +msgid "Do anything and everything" +msgstr "Fare di tutto e non importa cosa" + +#: html/Elements/Refresh:29 +msgid "Don't refresh this page." +msgstr "Non aggiornare questa pagina." + +#: html/Search/Elements/PickRestriction:113 +msgid "Don't show search results" +msgstr "Non mostrare i risultati della ricerca" + +#: html/Ticket/Elements/ShowTransaction:104 +msgid "Download" +msgstr "Download" + +#: html/Elements/SelectDateType:31 +#: html/Ticket/Create.html:166 +#: html/Ticket/Elements/EditDates:44 +#: html/Ticket/Elements/ShowDates:42 +#: lib/RT/Ticket_Overlay.pm:1170 +msgid "Due" +msgstr "Termine" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Due date '%1' could not be parsed" +msgstr "La data termine '%1' non è stata interpretata" + +#. ($1, $msg) +#: bin/rt-commit-handler:753 +msgid "ERROR: Couldn't load ticket '%1': %2.\\n" +msgstr "ERRORE: impossibile caricare il ticket '%1' : %2.\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Edit" +msgstr "Modifica" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Edit Conditions" +msgstr "Modifica Condizioni" + +#. ($Queue->Name) +#: html/Admin/Queues/CustomFields.html:44 +msgid "Edit Custom Fields for %1" +msgstr "Modifica i Campi Personalizzati per %1" + +#: html/Ticket/ModifyLinks.html:35 +msgid "Edit Relationships" +msgstr "Modifica Relazioni" + +#. ($QueueObj->Name) +#: html/Admin/Queues/Templates.html:41 +msgid "Edit Templates for queue %1" +msgstr "Modifica i modelli per la coda %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Edit keywords" +msgstr "Modifica parole chiave" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Edit scrips" +msgstr "Modifica scrips" + +#: html/Admin/Global/index.html:45 +msgid "Edit system templates" +msgstr "Modifca i modelli di sistema" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Edit templates for %1" +msgstr "Modifica i modelli per %1" + +#. ($QueueObj->Name) +#. ($QueueObj->Id) +#: html/Admin/Elements/ModifyQueue:24 +#: html/Admin/Queues/Modify.html:117 +msgid "Editing Configuration for queue %1" +msgstr "Modifica la Configurazione per la coda %1" + +#. ($UserObj->Name) +#: html/Admin/Elements/ModifyUser:24 +msgid "Editing Configuration for user %1" +msgstr "Modifica la Configurazione per l'utente %1" + +#. ($CustomFieldObj->Name()) +#: html/Admin/Elements/EditCustomField:90 +msgid "Editing CustomField %1" +msgstr "Modifica il CampoPersonalizzato %1" + +#. ($Group->Name) +#: html/Admin/Groups/Members.html:31 +msgid "Editing membership for group %1" +msgstr "Modifica i membri per il gruppo %1" + +#. ($Group->Name) +#: html/User/Groups/Members.html:128 +msgid "Editing membership for personal group %1" +msgstr "Modifica i membri per il gruppo personale %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Editing template %1" +msgstr "Modifica il modello %1" + +#: lib/RT/Ticket_Overlay.pm:2621 +#: lib/RT/Ticket_Overlay.pm:2689 +msgid "Either base or target must be specified" +msgstr "Uno almeno tra base e target deve essere specificato" + +#: html/Admin/Users/Modify.html:52 +#: html/Admin/Users/Prefs.html:45 +#: html/Elements/SelectUsers:26 +#: html/Ticket/Elements/AddWatchers:55 +#: html/User/Prefs.html:41 +msgid "Email" +msgstr "Email" + +#: lib/RT/User_Overlay.pm:187 +msgid "Email address in use" +msgstr "Inidirizzo email in uso" + +#: html/Admin/Elements/ModifyUser:41 +msgid "EmailAddress" +msgstr "IndirizzoEmail" + +#: html/Admin/Elements/ModifyUser:53 +msgid "EmailEncoding" +msgstr "EmailEncoding" + +#: html/Admin/Elements/EditCustomField:50 +msgid "Enabled (Unchecking this box disables this custom field)" +msgstr "Abilitato (Togliere il segno di spunta disabilita questo campo personalizzato)" + +#: html/Admin/Groups/Modify.html:52 +#: html/User/Groups/Modify.html:52 +msgid "Enabled (Unchecking this box disables this group)" +msgstr "Abilitato (Togliere il segno di spunta disabilita questo gruppo)" + +#: html/Admin/Queues/Modify.html:83 +msgid "Enabled (Unchecking this box disables this queue)" +msgstr "Abilitato (Togliere il segno di spunta disabilita questa coda)" + +#: html/Admin/Elements/EditCustomFields:98 +msgid "Enabled Custom Fields" +msgstr "Campi Personalizzati Abilitati" + +#: html/Admin/Queues/index.html:55 +msgid "Enabled Queues" +msgstr "Code Abilitate" + +#. (loc_fuzzy($msg)) +#: html/Admin/Elements/EditCustomField:106 +#: html/Admin/Groups/Modify.html:116 +#: html/Admin/Queues/Modify.html:139 +#: html/Admin/Users/Modify.html:282 +#: html/User/Groups/Modify.html:116 +msgid "Enabled status %1" +msgstr "Stato %1 abilitato" + +#: lib/RT/CustomField_Overlay.pm:427 +msgid "Enter multiple values" +msgstr "Inserire valori multipli" + +#: lib/RT/CustomField_Overlay.pm:424 +msgid "Enter one value" +msgstr "Inserire un valore" + +#: html/Ticket/Elements/EditLinks:111 +msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces." +msgstr "Inserire tickets o URI di tickets da collegare. Separare più valori con spazi." + +#: html/Elements/Login:38 +#: html/SelfService/Error.html:24 +#: html/SelfService/Error.html:25 +msgid "Error" +msgstr "Errore" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Error adding watcher" +msgstr "Errore cercando di aggiungere un osservatore" + +#: lib/RT/Queue_Overlay.pm:554 +msgid "Error in parameters to Queue->AddWatcher" +msgstr "Errore nei parametri di Queue->AddWatcher" + +#: lib/RT/Queue_Overlay.pm:712 +msgid "Error in parameters to Queue->DelWatcher" +msgstr "Errore nei parametri di Queue->DelWatcher" + +#: lib/RT/Ticket_Overlay.pm:1355 +msgid "Error in parameters to Ticket->AddWatcher" +msgstr "Errore nei parametri di Ticket->AddWatcher" + +#: lib/RT/Ticket_Overlay.pm:1531 +msgid "Error in parameters to Ticket->DelWatcher" +msgstr "Errore nei parametri di Ticket->DelWatcher" + +#: etc/initialdata:20 +msgid "Everyone" +msgstr "Chiunque" + +#: bin/rt-crontool:193 +msgid "Example:" +msgstr "Esempio:" + +#: html/Admin/Elements/ModifyUser:63 +msgid "ExternalAuthId" +msgstr "ExternalAuthId" + +#: html/Admin/Elements/ModifyUser:57 +msgid "ExternalContactInfoId" +msgstr "ExternalContactInfoId" + +#: html/Admin/Users/Modify.html:72 +msgid "Extra info" +msgstr "Informazioni aggiuntive" + +#: lib/RT/User_Overlay.pm:301 +msgid "Failed to find 'Privileged' users pseudogroup." +msgstr "Impossibile trovare il pseudogruppo 'Privilegiato' di utenti." + +#: lib/RT/User_Overlay.pm:308 +msgid "Failed to find 'Unprivileged' users pseudogroup" +msgstr "Impossibile trovare il pseudogruppo 'Non Privilegiato' di utenti." + +#. ($modname, $@) +#: bin/rt-crontool:137 +msgid "Failed to load module %1. (%2)" +msgstr "Errore nel caricare il modulo %1. (%2)" + +#: lib/RT/Date.pm:411 +msgid "Feb." +msgstr "Feb." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "February" +msgstr "Febbraio" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Fin" +msgstr "Fin" + +#: html/Ticket/Create.html:154 +#: html/Ticket/Elements/EditBasics:58 +#: lib/RT/Tickets_Overlay.pm:1090 +msgid "Final Priority" +msgstr "Priorità Finale" + +#: lib/RT/Ticket_Overlay.pm:1161 +msgid "FinalPriority" +msgstr "Priorità Finale" + +#: html/Admin/Queues/People.html:60 +#: html/Ticket/Elements/EditPeople:33 +msgid "Find group whose" +msgstr "Cerca il gruppo che" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Find new/open tickets" +msgstr "Cerca tickets nuovi/aperti" + +#: html/Admin/Queues/People.html:56 +#: html/Admin/Users/index.html:45 +#: html/Ticket/Elements/EditPeople:29 +msgid "Find people whose" +msgstr "Cerca le persone che" + +#: html/Search/Listing.html:107 +msgid "Find tickets" +msgstr "Cerca tickets" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Finish Approval" +msgstr "Approvazione Finale" + +#: html/Ticket/Elements/Tabs:57 +msgid "First" +msgstr "Primo" + +#: html/Search/Listing.html:40 +msgid "First page" +msgstr "Prima Pagina" + +#: docs/design_docs/string-extraction-guide.txt:33 +msgid "Foo Bar Baz" +msgstr "Foo Bar Baz" + +#: docs/design_docs/string-extraction-guide.txt:24 +msgid "Foo!" +msgstr "Foo!" + +#: html/Search/Bulk.html:86 +msgid "Force change" +msgstr "Forza il cambiamento" + +#. ($ticketcount) +#: html/Search/Listing.html:105 +msgid "Found %quant(%1,ticket)" +msgstr "Trovati %quant(%1,ticket)" + +#: lib/RT/Interface/Web.pm:901 +msgid "Found Object" +msgstr "Trovato Oggetto" + +#: html/Admin/Elements/ModifyUser:43 +msgid "FreeformContactInfo" +msgstr "FreeformContactInfo" + +#: lib/RT/CustomField_Overlay.pm:37 +msgid "FreeformMultiple" +msgstr "FreeformMultiple" + +#: lib/RT/CustomField_Overlay.pm:36 +msgid "FreeformSingle" +msgstr "FreeformSingle" + +#: lib/RT/Date.pm:391 +msgid "Fri." +msgstr "Gio." + +#: html/Ticket/Elements/ShowHistory:40 +#: html/Ticket/Elements/ShowHistory:50 +msgid "Full headers" +msgstr "Intestazioni Estese" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Getting the current user from a pgp sig\\n" +msgstr "Sto prendendo l'utente corrente da una firma pgp\\n" + +#. ($New->Name) +#: lib/RT/Transaction_Overlay.pm:592 +msgid "Given to %1" +msgstr "Assegnato a %1" + +#: html/Admin/Elements/Tabs:40 +#: html/Admin/index.html:37 +msgid "Global" +msgstr "Globale" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Global Keyword Selections" +msgstr "Selezione Globale delle Parole Chiave" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Global Scrips" +msgstr "Scrips Globali" + +#. (loc($Template->Name)) +#: html/Admin/Elements/SelectTemplate:37 +msgid "Global template: %1" +msgstr "Modello globale: %1" + +#: html/Admin/Elements/EditCustomFields:74 +#: html/Admin/Queues/People.html:58 +#: html/Admin/Queues/People.html:62 +#: html/Admin/Queues/index.html:43 +#: html/Admin/Users/index.html:48 +#: html/Ticket/Elements/EditPeople:31 +#: html/Ticket/Elements/EditPeople:35 +#: html/index.html:40 +msgid "Go!" +msgstr "Vai!" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Good pgp sig from %1\\n" +msgstr "Firma pgp valida da %1\\n" + +#: html/Search/Listing.html:49 +msgid "Goto page" +msgstr "Vai a pagina" + +#: html/Elements/GotoTicket:24 +#: html/SelfService/Elements/GotoTicket:24 +msgid "Goto ticket" +msgstr "Vai al ticket" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Grand" +msgstr "Grand" + +#: html/Ticket/Elements/AddWatchers:45 +#: html/User/Elements/DelegateRights:77 +msgid "Group" +msgstr "Gruppo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Group %1 %2: %3" +msgstr "Gruppo %1 %2: %3" + +#: html/Admin/Elements/GroupTabs:44 +#: html/Admin/Elements/QueueTabs:56 +#: html/Admin/Elements/SystemTabs:43 +#: html/Admin/Global/index.html:54 +msgid "Group Rights" +msgstr "Diritti di Gruppo" + +#: lib/RT/Group_Overlay.pm:964 +msgid "Group already has member" +msgstr "Il gruppo ha già il membro" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Group could not be created." +msgstr "Il gruppo non può essere creato." + +#. ($create_msg) +#: html/Admin/Groups/Modify.html:76 +msgid "Group could not be created: %1" +msgstr "Il gruppo non può essere creato: %1" + +#: lib/RT/Group_Overlay.pm:496 +msgid "Group created" +msgstr "Gruppo creato" + +#: lib/RT/Group_Overlay.pm:1132 +msgid "Group has no such member" +msgstr "Il gruppo non ho questo membro" + +#: lib/RT/Group_Overlay.pm:944 +#: lib/RT/Queue_Overlay.pm:627 +#: lib/RT/Queue_Overlay.pm:687 +#: lib/RT/Ticket_Overlay.pm:1428 +#: lib/RT/Ticket_Overlay.pm:1506 +msgid "Group not found" +msgstr "Gruppo non trovato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Group not found.\\n" +msgstr "Gruppo non trovato.\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Group not specified.\\n" +msgstr "Gruppo non specificato.\\n" + +#: html/Admin/Elements/SelectNewGroupMembers:34 +#: html/Admin/Elements/Tabs:34 +#: html/Admin/Groups/Members.html:63 +#: html/Admin/Queues/People.html:82 +#: html/Admin/index.html:31 +#: html/User/Groups/Members.html:66 +msgid "Groups" +msgstr "Gruppi" + +#: lib/RT/Group_Overlay.pm:970 +msgid "Groups can't be members of their members" +msgstr "I gruppi non possono essere membri dei loro membri" + +#: lib/RT/Interface/CLI.pm:72 +msgid "Hello!" +msgstr "Ciao!" + +#. ($name) +#: docs/design_docs/string-extraction-guide.txt:40 +msgid "Hello, %1" +msgstr "Ciao, %1" + +#: html/Ticket/Elements/ShowHistory:29 +#: html/Ticket/Elements/Tabs:87 +msgid "History" +msgstr "Storia" + +#: html/Admin/Elements/ModifyUser:67 +msgid "HomePhone" +msgstr "TelefonoCasa" + +#: html/Elements/Tabs:43 +msgid "Homepage" +msgstr "Homepage" + +#. (6) +#: lib/RT/Base.pm:73 +msgid "I have %quant(%1,concrete mixer)." +msgstr "Ho %quant(%1,concrete mixer)." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "I have [quant,_1,concrete mixer]." +msgstr "Ho [quant,_1,concrete mixer]." + +#: html/Ticket/Elements/ShowBasics:26 +#: lib/RT/Tickets_Overlay.pm:1017 +msgid "Id" +msgstr "Id" + +#: html/Admin/Users/Modify.html:43 +#: html/User/Prefs.html:38 +msgid "Identity" +msgstr "Identità " + +#: etc/upgrade/2.1.71:86 +msgid "If an approval is rejected, reject the original and delete pending approvals" +msgstr "Se una richiesta di approvazione è rifiutata, rifiuta l'originale e elimina le richieste di approvazione pendenti" + +#: bin/rt-crontool:189 +msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT." +msgstr "Se questo strumento viene utilizzato con setgid, un utente locale mlintenzionato può usrae questo strumento per ottenere accesso amministrativo su RT." + +#: html/Admin/Queues/People.html:104 +#: html/Ticket/Modify.html:38 +#: html/Ticket/ModifyAll.html:93 +#: html/Ticket/ModifyPeople.html:37 +msgid "If you've updated anything above, be sure to" +msgstr "Se hai aggiornato qualchecosa qui sopra, assicurati di" + +#: lib/RT/Interface/Web.pm:893 +msgid "Illegal value for %1" +msgstr "Valore non valido per %1" + +#: lib/RT/Interface/Web.pm:896 +msgid "Immutable field" +msgstr "Campo immutabile" + +#: html/Admin/Elements/EditCustomFields:73 +msgid "Include disabled custom fields in listing." +msgstr "Includi nella lista i campi personalizzati disabilitati." + +#: html/Admin/Queues/index.html:42 +msgid "Include disabled queues in listing." +msgstr "Includi nella lista le code disabilitate." + +#: html/Admin/Users/index.html:46 +msgid "Include disabled users in search." +msgstr "Includi nella ricerca gli utenti disabilitati." + +#: lib/RT/Tickets_Overlay.pm:1066 +msgid "Initial Priority" +msgstr "Priorità Iniziale" + +#: lib/RT/Ticket_Overlay.pm:1160 +#: lib/RT/Ticket_Overlay.pm:1162 +msgid "InitialPriority" +msgstr "Priorità Iniziale" + +#: lib/RT/ScripAction_Overlay.pm:104 +msgid "Input error" +msgstr "Errore in Input" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Interest noted" +msgstr "Interesse annotato" + +#: lib/RT/Ticket_Overlay.pm:3795 +msgid "Internal Error" +msgstr "Errore Interno" + +#. ($id->{error_message}) +#: lib/RT/Record.pm:142 +msgid "Internal Error: %1" +msgstr "Errore Interno: %1" + +#: lib/RT/Group_Overlay.pm:643 +msgid "Invalid Group Type" +msgstr "Tipo di Gruppo non valido" + +#: lib/RT/Principal_Overlay.pm:127 +msgid "Invalid Right" +msgstr "Diritto non valido" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Invalid Type" +msgstr "Tipo non valido" + +#: lib/RT/Interface/Web.pm:898 +msgid "Invalid data" +msgstr "Dati non validi" + +#: lib/RT/Ticket_Overlay.pm:438 +msgid "Invalid owner. Defaulting to 'nobody'." +msgstr "Proprietraio non valido. Verrà usato il default 'nobody'." + +#: lib/RT/Scrip_Overlay.pm:133 +#: lib/RT/Template_Overlay.pm:250 +msgid "Invalid queue" +msgstr "Coda non valida" + +#: lib/RT/ACE_Overlay.pm:243 +#: lib/RT/ACE_Overlay.pm:252 +#: lib/RT/ACE_Overlay.pm:258 +#: lib/RT/ACE_Overlay.pm:269 +#: lib/RT/ACE_Overlay.pm:274 +msgid "Invalid right" +msgstr "Diritto non valido" + +#. ($key) +#: lib/RT/Record.pm:117 +msgid "Invalid value for %1" +msgstr "Valore non valido per %1" + +#: lib/RT/Ticket_Overlay.pm:3433 +msgid "Invalid value for custom field" +msgstr "Valore non valido per il campo personalizzato" + +#: lib/RT/Ticket_Overlay.pm:345 +msgid "Invalid value for status" +msgstr "Valore non valido per lo stato" + +#: bin/rt-crontool:190 +msgid "It is incredibly important that nonprivileged users not be allowed to run this tool." +msgstr "E' estremamente importante che agli utenti non previlegiati non sia consentito eseguire questo strumento." + +#: bin/rt-crontool:191 +msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool." +msgstr "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool." + +#: bin/rt-crontool:162 +msgid "It takes several arguments:" +msgstr "Richide molteplici argomenti:" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Items pending my approval" +msgstr "Oggetti in attesa della mia approvazione" + +#: lib/RT/Date.pm:410 +msgid "Jan." +msgstr "Gen." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "January" +msgstr "Gennaio" + +#: lib/RT/Group_Overlay.pm:148 +msgid "Join or leave this group" +msgstr "Unisciti o lascia questo gruppo" + +#: lib/RT/Date.pm:416 +msgid "Jul." +msgstr "Lug." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "July" +msgstr "Luglio" + +#: html/Ticket/Elements/Tabs:98 +msgid "Jumbo" +msgstr "Jumbo" + +#: lib/RT/Date.pm:415 +msgid "Jun." +msgstr "Giu." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "June" +msgstr "Giugno" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Keyword" +msgstr "Parola chiave" + +#: html/Admin/Elements/ModifyUser:51 +msgid "Lang" +msgstr "Linguaggio" + +#: html/Ticket/Elements/Tabs:72 +msgid "Last" +msgstr "Ultimo" + +#: html/Ticket/Elements/EditDates:37 +#: html/Ticket/Elements/ShowDates:38 +msgid "Last Contact" +msgstr "Ultimo Contatto" + +#: html/Elements/SelectDateType:28 +msgid "Last Contacted" +msgstr "Ultimo Contatto" + +#: html/Search/Elements/TicketHeader:40 +msgid "Last Notified" +msgstr "Ultima Notifica" + +#: html/Elements/SelectDateType:29 +msgid "Last Updated" +msgstr "Ultimo Aggiornamento" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "LastUpdated" +msgstr "UltimoAggiornamento" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Left" +msgstr "Rimasti" + +#: html/Admin/Users/Modify.html:82 +msgid "Let this user access RT" +msgstr "Consenti a questo utente di accedere a RT" + +#: html/Admin/Users/Modify.html:86 +msgid "Let this user be granted rights" +msgstr "Concedi a questo utente che gli vengano assegnati i diritti" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Limiting owner to %1 %2" +msgstr "Limitare il proprietario %1 %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Limiting queue to %1 %2" +msgstr "Limitare la coda a %1 %2" + +#: lib/RT/Ticket_Overlay.pm:2703 +msgid "Link already exists" +msgstr "Il collegamento già esiste" + +#: lib/RT/Ticket_Overlay.pm:2715 +msgid "Link could not be created" +msgstr "Il collegamento non può essere creato" + +#. ($TransString) +#: lib/RT/Ticket_Overlay.pm:2723 +#: lib/RT/Ticket_Overlay.pm:2733 +msgid "Link created (%1)" +msgstr "Collegamento creato (%1)" + +#. ($TransString) +#: lib/RT/Ticket_Overlay.pm:2644 +msgid "Link deleted (%1)" +msgstr "Collegamento eliminato (%1)" + +#: lib/RT/Ticket_Overlay.pm:2650 +msgid "Link not found" +msgstr "Collegamento non trovato" + +#. ($Ticket->Id) +#: html/Ticket/ModifyLinks.html:24 +#: html/Ticket/ModifyLinks.html:28 +msgid "Link ticket #%1" +msgstr "Collega ticket n°%1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Link ticket %1" +msgstr "Collega ticket %1" + +#: html/Ticket/Elements/Tabs:96 +msgid "Links" +msgstr "Collegamenti" + +#: html/Admin/Users/Modify.html:113 +#: html/User/Prefs.html:84 +msgid "Location" +msgstr "Località " + +#. ($RT::LogDir) +#: lib/RT.pm:159 +msgid "" +"Log directory %1 not found or couldn't be written.\\n" +" RT can't run." +msgstr "" +"Directory di log %1 non trovata o non scrivibile.\\n" +" RT non può essere eseguito." + +#. ("<b>".$session{'CurrentUser'}->Name."</b>") +#: html/Elements/Header:56 +msgid "Logged in as %1" +msgstr "Collegato come %1" + +#: docs/design_docs/string-extraction-guide.txt:71 +#: html/Elements/Login:34 +#: html/Elements/Login:43 +#: html/Elements/Login:53 +msgid "Login" +msgstr "Collegamento" + +#: html/Elements/Header:53 +msgid "Logout" +msgstr "Scollegati" + +#: html/Search/Bulk.html:85 +msgid "Make Owner" +msgstr "Crea Proprietario" + +#: html/Search/Bulk.html:101 +msgid "Make Status" +msgstr "Crea Stato" + +#: html/Search/Bulk.html:108 +msgid "Make date Due" +msgstr "Crea data Scadenza" + +#: html/Search/Bulk.html:109 +msgid "Make date Resolved" +msgstr "Crea data Risolto" + +#: html/Search/Bulk.html:106 +msgid "Make date Started" +msgstr "Crea data Iniziato" + +#: html/Search/Bulk.html:105 +msgid "Make date Starts" +msgstr "Crea data Inizia" + +#: html/Search/Bulk.html:107 +msgid "Make date Told" +msgstr "Crea data Detto" + +#: html/Search/Bulk.html:98 +msgid "Make priority" +msgstr "Crea priorità " + +#: html/Search/Bulk.html:99 +msgid "Make queue" +msgstr "Crea coda" + +#: html/Search/Bulk.html:97 +msgid "Make subject" +msgstr "Crea oggetto" + +#: html/Admin/index.html:32 +msgid "Manage groups and group membership" +msgstr "Gestisci i gruppi e le appartenenze" + +#: html/Admin/index.html:38 +msgid "Manage properties and configuration which apply to all queues" +msgstr "Gestisci le proprietà e le configurazioni che si applicano a tutte le code" + +#: html/Admin/index.html:35 +msgid "Manage queues and queue-specific properties" +msgstr "Gestisci le code e le propietà specifiche delle code" + +#: html/Admin/index.html:29 +msgid "Manage users and passwords" +msgstr "Gestisci gli utenti e le password" + +#: lib/RT/Date.pm:412 +msgid "Mar." +msgstr "Mar." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "March" +msgstr "Marzo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "May" +msgstr "Maggio" + +#: lib/RT/Date.pm:414 +msgid "May." +msgstr "Mag." + +#: lib/RT/Group_Overlay.pm:981 +msgid "Member added" +msgstr "Aggiunto membro" + +#: lib/RT/Group_Overlay.pm:1139 +msgid "Member deleted" +msgstr "Eliminato membro" + +#: lib/RT/Group_Overlay.pm:1143 +msgid "Member not deleted" +msgstr "Membro non eliminato" + +#: html/Elements/SelectLinkType:25 +msgid "Member of" +msgstr "Membro di" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "MemberOf" +msgstr "MembroDi" + +#: html/Admin/Elements/GroupTabs:41 +#: html/User/Elements/GroupTabs:41 +msgid "Members" +msgstr "Membri" + +#: lib/RT/Ticket_Overlay.pm:2890 +msgid "Merge Successful" +msgstr "Unione avvenuta con Successo" + +#: lib/RT/Ticket_Overlay.pm:2810 +msgid "Merge failed. Couldn't set EffectiveId" +msgstr "Unione fallita. Impossibile impostare EffectiveId" + +#: html/Ticket/Elements/EditLinks:114 +msgid "Merge into" +msgstr "Unisci in" + +#: html/Ticket/Update.html:101 +msgid "Message" +msgstr "Messaggio" + +#: lib/RT/Interface/Web.pm:900 +msgid "Missing a primary key?: %1" +msgstr "Manca una chiave primaria?: %1" + +#: html/Admin/Users/Modify.html:168 +#: html/User/Prefs.html:53 +msgid "Mobile" +msgstr "Cellulare" + +#: html/Admin/Elements/ModifyUser:71 +msgid "MobilePhone" +msgstr "TelefonoCellulare" + +#: lib/RT/Queue_Overlay.pm:69 +msgid "Modify Access Control List" +msgstr "Modifca la Lista Controllo Accessi" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify Custom Field %1" +msgstr "Modifica il Campo Personalizzato %1" + +#: html/Admin/Global/CustomFields.html:43 +#: html/Admin/Global/index.html:50 +msgid "Modify Custom Fields which apply to all queues" +msgstr "Modifica i Campi Personalizzati validi per tutte le code" + +#: lib/RT/Queue_Overlay.pm:72 +msgid "Modify Scrip templates for this queue" +msgstr "Modifica i modelli di Scips per questa coda" + +#: lib/RT/Queue_Overlay.pm:75 +msgid "Modify Scrips for this queue" +msgstr "Modifica gli Scrips per questa coda" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify System ACLS" +msgstr "Modifica le LCA di Sistema" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify Template %1" +msgstr "Modifica il Modello %1" + +#. ($QueueObj->Name()) +#: html/Admin/Queues/CustomField.html:44 +msgid "Modify a CustomField for queue %1" +msgstr "Modifica un CampoPersonalizzato per la coda %1" + +#: html/Admin/Global/CustomField.html:52 +msgid "Modify a CustomField which applies to all queues" +msgstr "Modifica un CampoPersonalizzato valido per tutte le code" + +#. ($QueueObj->Name) +#: html/Admin/Queues/Scrip.html:53 +msgid "Modify a scrip for queue %1" +msgstr "Modifica uno scrip per la coda %1" + +#: html/Admin/Global/Scrip.html:47 +msgid "Modify a scrip which applies to all queues" +msgstr "Modifica uno scrip valido per tutte le code" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify dates for # %1" +msgstr "Modifica le date per n° %1" + +#. ($TicketObj->Id) +#: html/Ticket/ModifyDates.html:24 +#: html/Ticket/ModifyDates.html:28 +msgid "Modify dates for #%1" +msgstr "Modifica le date per n°%1" + +#. ($TicketObj->Id) +#: html/Ticket/ModifyDates.html:34 +msgid "Modify dates for ticket # %1" +msgstr "Modifica le date per il ticket n° %1" + +#: html/Admin/Global/GroupRights.html:24 +#: html/Admin/Global/GroupRights.html:27 +#: html/Admin/Global/index.html:55 +msgid "Modify global group rights" +msgstr "Modifica i diritti di gruppo globali" + +#: html/Admin/Global/GroupRights.html:32 +msgid "Modify global group rights." +msgstr "Modifica i diritti di gruppo globali." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify global rights for groups" +msgstr "Modifica i diritti di gruppo globali" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify global rights for users" +msgstr "Modifica i diritti globali per gli utenti" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify global scrips" +msgstr "Modifica gli scrips globali" + +#: html/Admin/Global/UserRights.html:24 +#: html/Admin/Global/UserRights.html:27 +#: html/Admin/Global/index.html:59 +msgid "Modify global user rights" +msgstr "Modifica i diritti globali per gli utenti" + +#: html/Admin/Global/UserRights.html:32 +msgid "Modify global user rights." +msgstr "Modifica i diritti globali per gli utenti." + +#: lib/RT/Group_Overlay.pm:145 +msgid "Modify group metadata or delete group" +msgstr "Modifica i metadati di gruppo o elimina un gruppo" + +#. ($GroupObj->Name) +#: html/Admin/Groups/GroupRights.html:24 +#: html/Admin/Groups/GroupRights.html:28 +#: html/Admin/Groups/GroupRights.html:34 +msgid "Modify group rights for group %1" +msgstr "Modifica i diritti di gruppo per il gruppo %1" + +#. ($QueueObj->Name) +#: html/Admin/Queues/GroupRights.html:24 +#: html/Admin/Queues/GroupRights.html:28 +msgid "Modify group rights for queue %1" +msgstr "Modifica i diritti di gruppo per la coda %1" + +#: lib/RT/Group_Overlay.pm:147 +msgid "Modify membership roster for this group" +msgstr "Modofica i membri di questo gruppo" + +#: lib/RT/System.pm:60 +msgid "Modify one's own RT account" +msgstr "Modifica il proprio account RT" + +#. ($QueueObj->Name) +#: html/Admin/Queues/People.html:24 +#: html/Admin/Queues/People.html:28 +msgid "Modify people related to queue %1" +msgstr "Modifica le persone relative alla coda %1" + +#. ($Ticket->id) +#. ($Ticket->Id) +#: html/Ticket/ModifyPeople.html:24 +#: html/Ticket/ModifyPeople.html:28 +#: html/Ticket/ModifyPeople.html:34 +msgid "Modify people related to ticket #%1" +msgstr "Modifica le persone relative al ticket n°%1" + +#. ($QueueObj->Name) +#: html/Admin/Queues/Scrips.html:43 +msgid "Modify scrips for queue %1" +msgstr "Modifica gli scrips per la coda %1" + +#: html/Admin/Global/Scrips.html:43 +#: html/Admin/Global/index.html:41 +msgid "Modify scrips which apply to all queues" +msgstr "Modifica gli scrips validi per tutte le code" + +#. (loc($TemplateObj->Name())) +#. ($TemplateObj->id) +#: html/Admin/Global/Template.html:24 +#: html/Admin/Global/Template.html:29 +#: html/Admin/Global/Template.html:80 +#: html/Admin/Queues/Template.html:77 +msgid "Modify template %1" +msgstr "Modifica modello %1" + +#: html/Admin/Global/Templates.html:43 +msgid "Modify templates which apply to all queues" +msgstr "Modifica i modelli validi per tutte le code" + +#. ($Group->Name) +#: html/Admin/Groups/Modify.html:86 +#: html/User/Groups/Modify.html:85 +msgid "Modify the group %1" +msgstr "Modifica il gruppo %1" + +#: lib/RT/Queue_Overlay.pm:70 +msgid "Modify the queue watchers" +msgstr "Modifica gli osservatori della coda" + +#. ($UserObj->Name) +#: html/Admin/Users/Modify.html:235 +msgid "Modify the user %1" +msgstr "Modifica l'utente %1" + +#. ($Ticket->Id) +#: html/Ticket/ModifyAll.html:36 +msgid "Modify ticket # %1" +msgstr "Modifica il ticket n° %1" + +#. ($TicketObj->Id) +#: html/Ticket/Modify.html:24 +#: html/Ticket/Modify.html:27 +#: html/Ticket/Modify.html:33 +msgid "Modify ticket #%1" +msgstr "Modifica il ticket n°%1" + +#: lib/RT/Queue_Overlay.pm:87 +msgid "Modify tickets" +msgstr "Modifica i tickets" + +#. ($GroupObj->Name) +#: html/Admin/Groups/UserRights.html:24 +#: html/Admin/Groups/UserRights.html:28 +#: html/Admin/Groups/UserRights.html:34 +msgid "Modify user rights for group %1" +msgstr "Modifica i diritti utente per il gruppo %1" + +#. ($QueueObj->Name) +#: html/Admin/Queues/UserRights.html:24 +#: html/Admin/Queues/UserRights.html:28 +msgid "Modify user rights for queue %1" +msgstr "Modifica i diritti dell'utente per la coda %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Modify watchers for queue '%1'" +msgstr "Modifica gli osservatori per la coda '%1'" + +#: lib/RT/Queue_Overlay.pm:69 +msgid "ModifyACL" +msgstr "ModificaLCA" + +#: lib/RT/Group_Overlay.pm:148 +msgid "ModifyOwnMembership" +msgstr "ModificaPropriaAppartenenza" + +#: lib/RT/Queue_Overlay.pm:70 +msgid "ModifyQueueWatchers" +msgstr "ModificaOsservatoriCoda" + +#: lib/RT/Queue_Overlay.pm:75 +msgid "ModifyScrips" +msgstr "ModificaScrips" + +#: lib/RT/System.pm:60 +msgid "ModifySelf" +msgstr "ModificaSeStesso" + +#: lib/RT/Queue_Overlay.pm:72 +msgid "ModifyTemplate" +msgstr "ModificaModello" + +#: lib/RT/Queue_Overlay.pm:87 +msgid "ModifyTicket" +msgstr "ModificaTicket" + +#: lib/RT/Date.pm:387 +msgid "Mon." +msgstr "Lun." + +#. ($name) +#: html/Ticket/Elements/ShowRequestor:41 +msgid "More about %1" +msgstr "Altre info su %1" + +#: html/Admin/Elements/EditCustomFields:60 +msgid "Move down" +msgstr "Move down" + +#: html/Admin/Elements/EditCustomFields:52 +msgid "Move up" +msgstr "Move up" + +#: html/Admin/Elements/SelectSingleOrMultiple:26 +msgid "Multiple" +msgstr "Multiple" + +#: lib/RT/User_Overlay.pm:178 +msgid "Must specify 'Name' attribute" +msgstr "Must specify 'Name' attribute" + +#. ($friendly_status) +#: html/SelfService/Elements/MyRequests:48 +msgid "My %1 tickets" +msgstr "I miei%1 tickets" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "My Approvals" +msgstr "Le mie richieste di Approvazione" + +#: html/Approvals/index.html:24 +#: html/Approvals/index.html:25 +msgid "My approvals" +msgstr "Le mie richieste di approvazione" + +#: html/Admin/Elements/AddCustomFieldValue:31 +#: html/Admin/Elements/EditCustomField:33 +#: html/Admin/Elements/ModifyTemplate:27 +#: html/Admin/Elements/ModifyUser:29 +#: html/Admin/Groups/Modify.html:43 +#: html/Elements/SelectGroups:25 +#: html/Elements/SelectUsers:27 +#: html/User/Groups/Modify.html:43 +msgid "Name" +msgstr "Nome" + +#: lib/RT/User_Overlay.pm:185 +msgid "Name in use" +msgstr "Name in use" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Need approval from system administrator" +msgstr "Need approval from system administrator" + +#: html/Ticket/Elements/ShowDates:51 +msgid "Never" +msgstr "Never" + +#: html/Elements/Quicksearch:29 +msgid "New" +msgstr "Nuovo" + +#: html/Admin/Elements/ModifyUser:31 +#: html/Admin/Users/Modify.html:92 +#: html/User/Prefs.html:64 +msgid "New Password" +msgstr "Nuova Password" + +#: etc/initialdata:317 +#: etc/upgrade/2.1.71:16 +msgid "New Pending Approval" +msgstr "New Pending Approval" + +#: html/Ticket/Elements/EditLinks:110 +msgid "New Relationships" +msgstr "New Relationships" + +#: html/Ticket/Elements/Tabs:35 +msgid "New Search" +msgstr "Nuova Ricerca" + +#: html/Admin/Global/CustomField.html:40 +#: html/Admin/Global/CustomFields.html:38 +#: html/Admin/Queues/CustomField.html:51 +#: html/Admin/Queues/CustomFields.html:39 +msgid "New custom field" +msgstr "Nuovo campo Personalizzato" + +#: html/Admin/Elements/GroupTabs:53 +#: html/User/Elements/GroupTabs:51 +msgid "New group" +msgstr "Nuovo gruppo" + +#: html/SelfService/Prefs.html:31 +msgid "New password" +msgstr "Nuova password" + +#: lib/RT/User_Overlay.pm:646 +msgid "New password notification sent" +msgstr "New password notification sent" + +#: html/Admin/Elements/QueueTabs:69 +msgid "New queue" +msgstr "Nuova coda" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "New request" +msgstr "Nuova richiesta" + +#: html/Admin/Elements/SelectRights:41 +msgid "New rights" +msgstr "Nuovi diritti" + +#: html/Admin/Global/Scrip.html:39 +#: html/Admin/Global/Scrips.html:38 +#: html/Admin/Queues/Scrip.html:42 +#: html/Admin/Queues/Scrips.html:52 +msgid "New scrip" +msgstr "Nuovo scrip" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "New search" +msgstr "Nuova ricerca" + +#: html/Admin/Global/Template.html:59 +#: html/Admin/Global/Templates.html:38 +#: html/Admin/Queues/Template.html:57 +#: html/Admin/Queues/Templates.html:49 +msgid "New template" +msgstr "Nuovo modello" + +#: html/SelfService/Elements/Tabs:47 +msgid "New ticket" +msgstr "Nuovo ticket" + +#: lib/RT/Ticket_Overlay.pm:2777 +msgid "New ticket doesn't exist" +msgstr "Il nuovo ticket non esiste" + +#: html/Admin/Elements/UserTabs:51 +msgid "New user" +msgstr "Nuovo utente" + +#: html/Admin/Elements/CreateUserCalled:25 +msgid "New user called" +msgstr "New user called" + +#: html/Admin/Queues/People.html:54 +#: html/Ticket/Elements/EditPeople:28 +msgid "New watchers" +msgstr "Nuovo osservatore" + +#: html/Admin/Users/Prefs.html:41 +msgid "New window setting" +msgstr "New window setting" + +#: html/Ticket/Elements/Tabs:68 +msgid "Next" +msgstr "Succesivo" + +#: html/Search/Listing.html:47 +msgid "Next page" +msgstr "Pagina succesiva" + +#: html/Admin/Elements/ModifyUser:49 +msgid "NickName" +msgstr "NickName" + +#: html/Admin/Users/Modify.html:62 +#: html/User/Prefs.html:45 +msgid "Nickname" +msgstr "Soprannome" + +#: html/Admin/Elements/EditCustomField:89 +#: html/Admin/Elements/EditCustomFields:104 +msgid "No CustomField" +msgstr "No CustomField" + +#: html/Admin/Groups/GroupRights.html:83 +#: html/Admin/Groups/UserRights.html:70 +msgid "No Group defined" +msgstr "No Group defined" + +#: html/Admin/Queues/GroupRights.html:95 +#: html/Admin/Queues/UserRights.html:67 +msgid "No Queue defined" +msgstr "No Queue defined" + +#: bin/rt-crontool:55 +msgid "No RT user found. Please consult your RT administrator.\\n" +msgstr "No RT user found. Please consult your RT administrator.\\n" + +#: html/Admin/Global/Template.html:78 +#: html/Admin/Queues/Template.html:75 +msgid "No Template" +msgstr "Nessun Modello" + +#: bin/rt-commit-handler:763 +msgid "No Ticket specified. Aborting ticket " +msgstr "No Ticket specified. Aborting ticket " + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "" +"No Ticket specified. Aborting ticket modifications\\n" +"\\n" +msgstr "" +"No Ticket specified. Aborting ticket modifications\\n" +"\\n" + +#: html/Approvals/Elements/Approve:45 +msgid "No action" +msgstr "No action" + +#: lib/RT/Interface/Web.pm:895 +msgid "No column specified" +msgstr "No column specified" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "No command found\\n" +msgstr "No command found\\n" + +#: html/Elements/ViewUser:35 +#: html/Ticket/Elements/ShowRequestor:44 +msgid "No comment entered about this user" +msgstr "No comment entered about this user" + +#: lib/RT/Ticket_Overlay.pm:2188 +#: lib/RT/Ticket_Overlay.pm:2256 +msgid "No correspondence attached" +msgstr "No correspondence attached" + +#. (ref $self) +#: lib/RT/Action/Generic.pm:149 +#: lib/RT/Condition/Generic.pm:175 +#: lib/RT/Search/ActiveTicketsInQueue.pm:55 +#: lib/RT/Search/Generic.pm:112 +msgid "No description for %1" +msgstr "Nessuna descrizione per %1" + +#: lib/RT/Users_Overlay.pm:151 +msgid "No group specified" +msgstr "No group specified" + +#: lib/RT/User_Overlay.pm:864 +msgid "No password set" +msgstr "No password set" + +#: lib/RT/Queue_Overlay.pm:258 +msgid "No permission to create queues" +msgstr "No permission to create code" + +#. ($QueueObj->Name) +#: lib/RT/Ticket_Overlay.pm:341 +msgid "No permission to create tickets in the queue '%1'" +msgstr "No permission to create tickets in the coda '%1'" + +#: lib/RT/User_Overlay.pm:151 +msgid "No permission to create users" +msgstr "No permission to create users" + +#: html/SelfService/Display.html:117 +msgid "No permission to display that ticket" +msgstr "No permission to display that ticket" + +#: html/SelfService/Update.html:51 +msgid "No permission to view update ticket" +msgstr "No permission to view update ticket" + +#: lib/RT/Queue_Overlay.pm:674 +#: lib/RT/Ticket_Overlay.pm:1487 +msgid "No principal specified" +msgstr "No principal specified" + +#: html/Admin/Queues/People.html:153 +#: html/Admin/Queues/People.html:163 +msgid "No principals selected." +msgstr "No principals selected." + +#: html/Admin/Queues/index.html:34 +msgid "No queues matching search criteria found." +msgstr "No code matching search criteria found." + +#: html/Admin/Elements/SelectRights:80 +msgid "No rights found" +msgstr "Nessun diritto trovato" + +#: html/Admin/Elements/SelectRights:32 +msgid "No rights granted." +msgstr "Nessun diritto concesso." + +#: html/Search/Bulk.html:148 +msgid "No search to operate on." +msgstr "No search to operate on." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "No ticket id specified" +msgstr "No ticket id specified" + +#: lib/RT/Transaction_Overlay.pm:477 +#: lib/RT/Transaction_Overlay.pm:515 +msgid "No transaction type specified" +msgstr "No transaction type specified" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "No user or email address specified" +msgstr "No user or email address specified" + +#: html/Admin/Users/index.html:35 +msgid "No users matching search criteria found." +msgstr "No users matching search criteria found." + +#: bin/rt-commit-handler:643 +msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n" +msgstr "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n" + +#: lib/RT/Interface/Web.pm:892 +msgid "No value sent to _Set!\\n" +msgstr "No value sent to _Set!\\n" + +#: html/Search/Elements/TicketRow:36 +msgid "Nobody" +msgstr "Nessuno" + +#: lib/RT/Interface/Web.pm:897 +msgid "Nonexistant field?" +msgstr "Nonexistant field?" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Not logged in" +msgstr "Not logged in" + +#: html/Elements/Header:58 +msgid "Not logged in." +msgstr "Non collegato." + +#: lib/RT/Date.pm:368 +msgid "Not set" +msgstr "Non valorizzato" + +#: html/NoAuth/Reminder.html:26 +msgid "Not yet implemented." +msgstr "Not yet implemented." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Not yet implemented...." +msgstr "Not yet implemented...." + +#: html/Approvals/Elements/Approve:48 +msgid "Notes" +msgstr "Notes" + +#: lib/RT/User_Overlay.pm:649 +msgid "Notification could not be sent" +msgstr "Notification could not be sent" + +#: etc/initialdata:94 +msgid "Notify AdminCcs" +msgstr "Notify AdminCcs" + +#: etc/initialdata:90 +msgid "Notify AdminCcs as Comment" +msgstr "Notify AdminCcs as Comment" + +#: etc/initialdata:121 +msgid "Notify Other Recipients" +msgstr "Notify Other Recipients" + +#: etc/initialdata:117 +msgid "Notify Other Recipients as Comment" +msgstr "Notify Other Recipients as Comment" + +#: etc/initialdata:86 +msgid "Notify Owner" +msgstr "Notify Proprietario" + +#: etc/initialdata:82 +msgid "Notify Owner as Comment" +msgstr "Notify Proprietario as Comment" + +#: etc/initialdata:319 +#: etc/upgrade/2.1.71:17 +msgid "Notify Owners and AdminCcs of new items pending their approval" +msgstr "Notify Proprietari and AdminCcs of new items pending their approval" + +#: etc/initialdata:78 +msgid "Notify Requestors" +msgstr "Notifica al Richiedente" + +#: etc/initialdata:104 +msgid "Notify Requestors and Ccs" +msgstr "Notifica ai Richiedenti e ai Ccs" + +#: etc/initialdata:99 +msgid "Notify Requestors and Ccs as Comment" +msgstr "Notifica ai Richiedenti e ai Ccs come Commento" + +#: etc/initialdata:113 +msgid "Notify Requestors, Ccs and AdminCcs" +msgstr "Notifica ai Richiedenti, Ccs e AdminCcs" + +#: etc/initialdata:109 +msgid "Notify Requestors, Ccs and AdminCcs as Comment" +msgstr "Notifica ai Richiedenti, Ccs a AdminCcs come Commento" + +#: lib/RT/Date.pm:420 +msgid "Nov." +msgstr "Nov." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "November" +msgstr "November" + +#: lib/RT/Record.pm:156 +msgid "Object could not be created" +msgstr "Object could not be created" + +#: lib/RT/Record.pm:175 +msgid "Object created" +msgstr "Object created" + +#: lib/RT/Date.pm:419 +msgid "Oct." +msgstr "Oct." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "October" +msgstr "October" + +#: html/Elements/SelectDateRelation:34 +msgid "On" +msgstr "On" + +#: etc/initialdata:155 +msgid "On Comment" +msgstr "On Comment" + +#: etc/initialdata:148 +msgid "On Correspond" +msgstr "On Correspond" + +#: etc/initialdata:137 +msgid "On Create" +msgstr "On Create" + +#: etc/initialdata:169 +msgid "On Owner Change" +msgstr "On Owner Change" + +#: etc/initialdata:177 +msgid "On Queue Change" +msgstr "On Queue Change" + +#: etc/initialdata:183 +msgid "On Resolve" +msgstr "On Resolve" + +#: etc/initialdata:161 +msgid "On Status Change" +msgstr "On Status Change" + +#: etc/initialdata:142 +msgid "On Transaction" +msgstr "On Transaction" + +#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>") +#: html/Approvals/Elements/PendingMyApproval:49 +msgid "Only show approvals for requests created after %1" +msgstr "Mostra le approvazioni solo per le richieste create dopo %1" + +#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>") +#: html/Approvals/Elements/PendingMyApproval:47 +msgid "Only show approvals for requests created before %1" +msgstr "Mostra le approvazioni solo per le richieste create prima %1" + +#: html/Elements/Quicksearch:30 +msgid "Open" +msgstr "Aperto" + +#: html/Ticket/Elements/Tabs:135 +msgid "Open it" +msgstr "Aprilo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Open requests" +msgstr "Richieste aperte" + +#: html/SelfService/Elements/Tabs:41 +msgid "Open tickets" +msgstr "Open tickets" + +#: html/Admin/Users/Prefs.html:40 +msgid "Open tickets (from listing) in a new window" +msgstr "Open tickets (from listing) in a new window" + +#: html/Admin/Users/Prefs.html:39 +msgid "Open tickets (from listing) in another window" +msgstr "Open tickets (from listing) in another window" + +#: etc/initialdata:133 +msgid "Open tickets on correspondence" +msgstr "Open tickets on correspondence" + +#: html/Search/Elements/PickRestriction:100 +msgid "Ordering and sorting" +msgstr "Visualizzazione e Ordinamento" + +#: html/Admin/Elements/ModifyUser:45 +#: html/Admin/Users/Modify.html:116 +#: html/Elements/SelectUsers:28 +#: html/User/Prefs.html:85 +msgid "Organization" +msgstr "Azienda" + +#. ($approving->Id, $approving->Subject) +#: html/Approvals/Elements/Approve:32 +msgid "Originating ticket: #%1" +msgstr "Originating ticket: n°%1" + +#: html/Admin/Elements/ModifyQueue:54 +#: html/Admin/Queues/Modify.html:68 +msgid "Over time, priority moves toward" +msgstr "Se scade il tempo, la priorità sale di" + +#: lib/RT/Queue_Overlay.pm:86 +msgid "Own tickets" +msgstr "Own tickets" + +#: lib/RT/Queue_Overlay.pm:86 +msgid "OwnTicket" +msgstr "PossiediTicket" + +#: etc/initialdata:38 +#: html/Elements/MyRequests:31 +#: html/SelfService/Elements/MyRequests:29 +#: html/Ticket/Create.html:47 +#: html/Ticket/Elements/EditPeople:42 +#: html/Ticket/Elements/EditPeople:43 +#: html/Ticket/Elements/ShowPeople:26 +#: html/Ticket/Update.html:62 +#: lib/RT/ACE_Overlay.pm:85 +#: lib/RT/Tickets_Overlay.pm:1243 +msgid "Owner" +msgstr "Proprietario" + +#. ($OldOwnerObj->Name, $NewOwnerObj->Name) +#: lib/RT/Ticket_Overlay.pm:3070 +msgid "Owner changed from %1 to %2" +msgstr "Proprietario changed from %1 to %2" + +#. ($Old->Name , $New->Name) +#: lib/RT/Transaction_Overlay.pm:581 +msgid "Owner forcibly changed from %1 to %2" +msgstr "Owner forcibly changed from %1 to %2" + +#: html/Search/Elements/PickRestriction:30 +msgid "Owner is" +msgstr "Il Proprietario è" + +#: html/Admin/Users/Modify.html:173 +#: html/User/Prefs.html:55 +msgid "Pager" +msgstr "Pager" + +#: html/Admin/Elements/ModifyUser:73 +msgid "PagerPhone" +msgstr "PagerPhone" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Parent" +msgstr "" + +#: html/Ticket/Create.html:181 +#: html/Ticket/Elements/EditLinks:126 +#: html/Ticket/Elements/EditLinks:57 +#: html/Ticket/Elements/ShowLinks:46 +msgid "Parents" +msgstr "Genitori" + +#: html/Elements/Login:51 +#: html/User/Prefs.html:60 +msgid "Password" +msgstr "Password" + +#: html/NoAuth/Reminder.html:24 +msgid "Password Reminder" +msgstr "Password Reminder" + +#: lib/RT/User_Overlay.pm:168 +#: lib/RT/User_Overlay.pm:867 +msgid "Password too short" +msgstr "Password too short" + +#. (loc_fuzzy($msg)) +#: html/Admin/Users/Modify.html:290 +#: html/User/Prefs.html:171 +msgid "Password: %1" +msgstr "Password: %1" + +#: html/Admin/Users/Modify.html:292 +msgid "Passwords do not match." +msgstr "Passwords do not match." + +#: html/User/Prefs.html:173 +msgid "Passwords do not match. Your password has not been changed" +msgstr "Passwords do not match. Your password has not been changed" + +#: html/Ticket/Elements/ShowSummary:44 +#: html/Ticket/Elements/Tabs:95 +#: html/Ticket/ModifyAll.html:50 +msgid "People" +msgstr "Persone" + +#: etc/initialdata:126 +msgid "Perform a user-defined action" +msgstr "Perform a user-defined action" + +#: lib/RT/ACE_Overlay.pm:230 +#: lib/RT/ACE_Overlay.pm:236 +#: lib/RT/ACE_Overlay.pm:562 +#: lib/RT/ACE_Overlay.pm:572 +#: lib/RT/ACE_Overlay.pm:582 +#: lib/RT/ACE_Overlay.pm:647 +#: lib/RT/CurrentUser.pm:82 +#: lib/RT/CurrentUser.pm:91 +#: lib/RT/CustomField_Overlay.pm:100 +#: lib/RT/CustomField_Overlay.pm:201 +#: lib/RT/CustomField_Overlay.pm:233 +#: lib/RT/CustomField_Overlay.pm:510 +#: lib/RT/CustomField_Overlay.pm:90 +#: lib/RT/Group_Overlay.pm:1094 +#: lib/RT/Group_Overlay.pm:1098 +#: lib/RT/Group_Overlay.pm:1107 +#: lib/RT/Group_Overlay.pm:1158 +#: lib/RT/Group_Overlay.pm:1162 +#: lib/RT/Group_Overlay.pm:1168 +#: lib/RT/Group_Overlay.pm:425 +#: lib/RT/Group_Overlay.pm:517 +#: lib/RT/Group_Overlay.pm:595 +#: lib/RT/Group_Overlay.pm:603 +#: lib/RT/Group_Overlay.pm:700 +#: lib/RT/Group_Overlay.pm:704 +#: lib/RT/Group_Overlay.pm:710 +#: lib/RT/Group_Overlay.pm:903 +#: lib/RT/Group_Overlay.pm:907 +#: lib/RT/Group_Overlay.pm:920 +#: lib/RT/Queue_Overlay.pm:539 +#: lib/RT/Queue_Overlay.pm:549 +#: lib/RT/Queue_Overlay.pm:563 +#: lib/RT/Queue_Overlay.pm:698 +#: lib/RT/Queue_Overlay.pm:707 +#: lib/RT/Queue_Overlay.pm:720 +#: lib/RT/Queue_Overlay.pm:930 +#: lib/RT/Scrip_Overlay.pm:125 +#: lib/RT/Scrip_Overlay.pm:136 +#: lib/RT/Scrip_Overlay.pm:196 +#: lib/RT/Scrip_Overlay.pm:429 +#: lib/RT/Template_Overlay.pm:283 +#: lib/RT/Template_Overlay.pm:87 +#: lib/RT/Template_Overlay.pm:93 +#: lib/RT/Ticket_Overlay.pm:1340 +#: lib/RT/Ticket_Overlay.pm:1350 +#: lib/RT/Ticket_Overlay.pm:1364 +#: lib/RT/Ticket_Overlay.pm:1517 +#: lib/RT/Ticket_Overlay.pm:1526 +#: lib/RT/Ticket_Overlay.pm:1539 +#: lib/RT/Ticket_Overlay.pm:1874 +#: lib/RT/Ticket_Overlay.pm:2012 +#: lib/RT/Ticket_Overlay.pm:2176 +#: lib/RT/Ticket_Overlay.pm:2243 +#: lib/RT/Ticket_Overlay.pm:2602 +#: lib/RT/Ticket_Overlay.pm:2674 +#: lib/RT/Ticket_Overlay.pm:2768 +#: lib/RT/Ticket_Overlay.pm:2783 +#: lib/RT/Ticket_Overlay.pm:2977 +#: lib/RT/Ticket_Overlay.pm:3205 +#: lib/RT/Ticket_Overlay.pm:3403 +#: lib/RT/Ticket_Overlay.pm:3565 +#: lib/RT/Ticket_Overlay.pm:3617 +#: lib/RT/Ticket_Overlay.pm:3782 +#: lib/RT/Transaction_Overlay.pm:465 +#: lib/RT/Transaction_Overlay.pm:472 +#: lib/RT/Transaction_Overlay.pm:501 +#: lib/RT/Transaction_Overlay.pm:508 +#: lib/RT/User_Overlay.pm:1354 +#: lib/RT/User_Overlay.pm:569 +#: lib/RT/User_Overlay.pm:604 +#: lib/RT/User_Overlay.pm:860 +#: lib/RT/User_Overlay.pm:961 +msgid "Permission Denied" +msgstr "Permission Denied" + +#: html/User/Elements/Tabs:34 +msgid "Personal Groups" +msgstr "Gruppi Personali" + +#: html/User/Groups/index.html:29 +#: html/User/Groups/index.html:39 +msgid "Personal groups" +msgstr "Gruppi personali" + +#: html/User/Elements/DelegateRights:36 +msgid "Personal groups:" +msgstr "Gruppi personali:" + +#: html/Admin/Users/Modify.html:155 +#: html/User/Prefs.html:48 +msgid "Phone numbers" +msgstr "Numeri Telefonici" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Placeholder" +msgstr "Placeholder" + +#: html/Elements/Header:51 +#: html/Elements/Tabs:52 +#: html/SelfService/Elements/Tabs:50 +#: html/SelfService/Prefs.html:24 +#: html/User/Prefs.html:24 +#: html/User/Prefs.html:27 +msgid "Preferences" +msgstr "Preferenze" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Prefs" +msgstr "Prefs" + +#: lib/RT/Action/Generic.pm:159 +msgid "Prepare Stubbed" +msgstr "Prepare Stubbed" + +#: html/Ticket/Elements/Tabs:60 +msgid "Prev" +msgstr "Precedente" + +#: html/Search/Listing.html:43 +msgid "Previous page" +msgstr "Previous page" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Pri" +msgstr "Pri" + +#. ($args{'PrincipalId'}) +#: lib/RT/ACE_Overlay.pm:132 +#: lib/RT/ACE_Overlay.pm:207 +#: lib/RT/ACE_Overlay.pm:551 +msgid "Principal %1 not found." +msgstr "Principal %1 not found." + +#: html/Search/Elements/PickRestriction:53 +#: html/Ticket/Create.html:153 +#: html/Ticket/Elements/EditBasics:53 +#: html/Ticket/Elements/ShowBasics:38 +#: lib/RT/Tickets_Overlay.pm:1041 +msgid "Priority" +msgstr "Priorità " + +#: html/Admin/Elements/ModifyQueue:50 +#: html/Admin/Queues/Modify.html:64 +msgid "Priority starts at" +msgstr "La priorità inizia da" + +#: etc/initialdata:25 +msgid "Privileged" +msgstr "Privilegiato" + +#. (loc_fuzzy($msg)) +#: html/Admin/Users/Modify.html:270 +#: html/User/Prefs.html:162 +msgid "Privileged status: %1" +msgstr "Stato previlegiato: %1" + +#: html/Admin/Users/index.html:61 +msgid "Privileged users" +msgstr "Utenti privilegiati" + +#: etc/initialdata:23 +#: etc/initialdata:29 +#: etc/initialdata:35 +#: etc/initialdata:59 +msgid "Pseudogroup for internal use" +msgstr "Pseudogroup for internal use" + +#: html/Elements/MyRequests:29 +#: html/Elements/MyTickets:29 +#: html/Elements/Quicksearch:28 +#: html/Search/Elements/PickRestriction:45 +#: html/SelfService/Create.html:32 +#: html/Ticket/Create.html:37 +#: html/Ticket/Elements/EditBasics:63 +#: html/Ticket/Elements/ShowBasics:42 +#: html/User/Elements/DelegateRights:79 +#: lib/RT/Tickets_Overlay.pm:882 +msgid "Queue" +msgstr "Coda" + +#. ($Queue) +#. ($id) +#: html/Admin/Queues/CustomField.html:41 +#: html/Admin/Queues/Scrip.html:49 +#: html/Admin/Queues/Scrips.html:45 +#: html/Admin/Queues/Templates.html:43 +msgid "Queue %1 not found" +msgstr "Queue %1 not found" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Queue '%1' not found\\n" +msgstr "Queue '%1' not found\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Queue Keyword Selections" +msgstr "Queue Keyword Selections" + +#: html/Admin/Elements/ModifyQueue:30 +#: html/Admin/Queues/Modify.html:42 +msgid "Queue Name" +msgstr "Nome della coda" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Queue Scrips" +msgstr "Queue Scrips" + +#: lib/RT/Queue_Overlay.pm:262 +msgid "Queue already exists" +msgstr "Queue already exists" + +#: lib/RT/Queue_Overlay.pm:271 +#: lib/RT/Queue_Overlay.pm:277 +msgid "Queue could not be created" +msgstr "Queue could not be created" + +#: html/Ticket/Create.html:204 +msgid "Queue could not be loaded." +msgstr "Queue could not be loaded." + +#: docs/design_docs/string-extraction-guide.txt:83 +#: lib/RT/Queue_Overlay.pm:281 +msgid "Queue created" +msgstr "Queue created" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Queue is not specified." +msgstr "Queue is not specified." + +#: html/SelfService/Display.html:70 +#: lib/RT/CustomField_Overlay.pm:97 +msgid "Queue not found" +msgstr "Queue not found" + +#: html/Admin/Elements/Tabs:37 +#: html/Admin/index.html:34 +msgid "Queues" +msgstr "Code" + +#: html/Elements/Quicksearch:24 +msgid "Quick search" +msgstr "Ricerca veloce" + +#. ($RT::VERSION) +#: html/Elements/Login:43 +msgid "RT %1" +msgstr "RT %1" + +#. ($RT::VERSION, $RT::rtname) +#: docs/design_docs/string-extraction-guide.txt:70 +msgid "RT %1 for %2" +msgstr "RT %1 per %2" + +#. ($RT::VERSION) +#: html/Elements/Footer:31 +msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>." +msgstr "RT %1 da <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n" +msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n" +msgstr "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n" + +#: html/Admin/index.html:24 +#: html/Admin/index.html:25 +msgid "RT Administration" +msgstr "RT Administration" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT Authentication error." +msgstr "RT Authentication error." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT Bounce: %1" +msgstr "RT Bounce: %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT Configuration error" +msgstr "RT Configuration error" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT Critical error. Message not recorded!" +msgstr "RT Critical error. Message not recorded!" + +#: html/Elements/Error:40 +#: html/SelfService/Error.html:40 +msgid "RT Error" +msgstr "RT Error" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT Received mail (%1) from itself." +msgstr "RT Received mail (%1) from itself." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT Recieved mail (%1) from itself." +msgstr "RT Recieved mail (%1) from itself." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT Self Service / Closed Tickets" +msgstr "RT Self Service / Closed Tickets" + +#: html/index.html:24 +#: html/index.html:27 +msgid "RT at a glance" +msgstr "Colpo d'occhio di RT" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT couldn't authenticate you" +msgstr "RT couldn't authenticate you" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT couldn't find requestor via its external database lookup" +msgstr "RT couldn't find requestor via its external database lookup" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT couldn't find the queue: %1" +msgstr "RT couldn't find the coda: %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT couldn't validate this PGP signature. \\n" +msgstr "RT couldn't validate this PGP signature. \\n" + +#. ($RT::rtname) +#: html/Elements/PageLayout:25 +msgid "RT for %1" +msgstr "RT per %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT for %1: %2" +msgstr "RT per %1: %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT has proccessed your commands" +msgstr "RT has proccessed your commands" + +#. ('2003') +#: html/Elements/Login:91 +msgid "RT is © Copyright 1996-%1 Jesse Vincent <jesse@bestpractical.com>. It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>" +msgstr "RT is © Copyright 1996-%1 Jesse Vincent <jesse@bestpractical.com>. RT viene distribuito con la <a href=\"http://www.gnu.org/copyleft/gpl.html\">Versione 2 della GNU General Public License.</a>" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT is © Copyright 1996-2002 Jesse Vincent <jesse@bestpractical.com>. It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>" +msgstr "RT is © Copyright 1996-2002 Jesse Vincent <jesse@bestpractical.com>. RT viene distribuito con la <a href=\"http://www.gnu.org/copyleft/gpl.html\">Versione 2 della GNU General Public License.</a>" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT thinks this message may be a bounce" +msgstr "RT thinks this message may be a bounce" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT will process this message as if it were unsigned.\\n" +msgstr "RT will process this message as if it were unsigned.\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RT's email command mode requires PGP authentication. Either you didn't sign your message, or your signature could not be verified." +msgstr "RT's email command mode requires PGP authentication. Either you didn't sign your message, or your signature could not be verified." + +#: html/Admin/Users/Modify.html:57 +#: html/Admin/Users/Prefs.html:51 +#: html/User/Prefs.html:43 +msgid "Real Name" +msgstr "Nome Reale" + +#: html/Admin/Elements/ModifyUser:47 +msgid "RealName" +msgstr "RealName" + +#: html/Ticket/Create.html:184 +#: html/Ticket/Elements/EditLinks:138 +#: html/Ticket/Elements/EditLinks:93 +#: html/Ticket/Elements/ShowLinks:70 +msgid "Referred to by" +msgstr "Riferito da" + +#: html/Elements/SelectLinkType:27 +#: html/Ticket/Create.html:183 +#: html/Ticket/Elements/EditLinks:134 +#: html/Ticket/Elements/EditLinks:79 +#: html/Ticket/Elements/ShowLinks:60 +msgid "Refers to" +msgstr "Fa riferimento a" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RefersTo" +msgstr "RefersTo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Refine" +msgstr "Refine" + +#: html/Search/Elements/PickRestriction:26 +msgid "Refine search" +msgstr "Rifinisci la ricerca" + +#. ($value/60) +#: html/Elements/Refresh:35 +msgid "Refresh this page every %1 minutes." +msgstr "Aggiorna questa pagina ogni %1 minuti." + +#: html/Ticket/Create.html:173 +#: html/Ticket/Elements/ShowSummary:61 +#: html/Ticket/ModifyAll.html:56 +msgid "Relationships" +msgstr "Relazioni" + +#: html/Search/Bulk.html:92 +msgid "Remove AdminCc" +msgstr "Remove AdminCc" + +#: html/Search/Bulk.html:90 +msgid "Remove Cc" +msgstr "Remove Cc" + +#: html/Search/Bulk.html:88 +msgid "Remove Requestor" +msgstr "Rimuovi il RIchiedente" + +#: html/Ticket/Elements/ShowTransaction:172 +#: html/Ticket/Elements/Tabs:121 +msgid "Reply" +msgstr "Risposta" + +#: lib/RT/Queue_Overlay.pm:84 +msgid "Reply to tickets" +msgstr "Rispondi ai tickets" + +#: lib/RT/Queue_Overlay.pm:84 +msgid "ReplyToTicket" +msgstr "RispondiAlTicket" + +#: etc/initialdata:44 +#: html/Ticket/Update.html:39 +#: lib/RT/ACE_Overlay.pm:86 +msgid "Requestor" +msgstr "Richiedente" + +#: html/Search/Elements/PickRestriction:37 +msgid "Requestor email address" +msgstr "Indirizzo emaildel richiedente" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Requestor(s)" +msgstr "Richiedente(i)" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RequestorAddresses" +msgstr "IndirizzoRichiedente" + +#: html/SelfService/Create.html:40 +#: html/Ticket/Create.html:55 +#: html/Ticket/Elements/EditPeople:47 +#: html/Ticket/Elements/ShowPeople:30 +msgid "Requestors" +msgstr "Richiedenti" + +#: html/Admin/Elements/ModifyQueue:60 +#: html/Admin/Queues/Modify.html:74 +msgid "Requests should be due in" +msgstr "Le richieste devono essere soddisfatte in" + +#: html/Elements/Submit:61 +msgid "Reset" +msgstr "Azzera" + +#: html/Admin/Users/Modify.html:158 +#: html/User/Prefs.html:49 +msgid "Residence" +msgstr "Casa" + +#: html/Ticket/Elements/Tabs:131 +msgid "Resolve" +msgstr "Risolvi" + +#. ($Ticket->id, $Ticket->Subject) +#: html/Ticket/Update.html:132 +msgid "Resolve ticket #%1 (%2)" +msgstr "Risolvi il ticket n°%1 (%2)" + +#: etc/initialdata:308 +#: html/Elements/SelectDateType:27 +#: lib/RT/Ticket_Overlay.pm:1169 +msgid "Resolved" +msgstr "Risolto" + +#: html/Search/Bulk.html:122 +#: html/Ticket/ModifyAll.html:72 +#: html/Ticket/Update.html:72 +msgid "Response to requestors" +msgstr "Risposta ai richiedenti" + +#: html/Elements/ListActions:25 +msgid "Results" +msgstr "Risultati" + +#: html/Search/Elements/PickRestriction:104 +msgid "Results per page" +msgstr "Risultati per pagina" + +#: html/Admin/Elements/ModifyUser:32 +#: html/Admin/Users/Modify.html:99 +#: html/User/Prefs.html:71 +msgid "Retype Password" +msgstr "Ridigita Password" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Right %1 not found for %2 %3 in scope %4 (%5)\\n" +msgstr "Right %1 not found for %2 %3 in scope %4 (%5)\\n" + +#: lib/RT/ACE_Overlay.pm:612 +msgid "Right Delegated" +msgstr "Right Delegated" + +#: lib/RT/ACE_Overlay.pm:302 +msgid "Right Granted" +msgstr "Right Granted" + +#: lib/RT/ACE_Overlay.pm:160 +msgid "Right Loaded" +msgstr "Right Loaded" + +#: lib/RT/ACE_Overlay.pm:677 +#: lib/RT/ACE_Overlay.pm:692 +msgid "Right could not be revoked" +msgstr "Right could not be revoked" + +#: html/User/Delegation.html:63 +msgid "Right not found" +msgstr "Right not found" + +#: lib/RT/ACE_Overlay.pm:542 +#: lib/RT/ACE_Overlay.pm:637 +msgid "Right not loaded." +msgstr "Right not loaded." + +#: lib/RT/ACE_Overlay.pm:688 +msgid "Right revoked" +msgstr "Right revoked" + +#: html/Admin/Elements/UserTabs:40 +msgid "Rights" +msgstr "Diritti" + +#. ($object_type) +#: lib/RT/Interface/Web.pm:791 +msgid "Rights could not be granted for %1" +msgstr "I diritti non possono essere concessi per %1" + +#. ($object_type) +#: lib/RT/Interface/Web.pm:824 +msgid "Rights could not be revoked for %1" +msgstr "I diritti non possono essere revocaqti per %1" + +#: html/Admin/Global/GroupRights.html:50 +#: html/Admin/Queues/GroupRights.html:51 +msgid "Roles" +msgstr "Ruoli" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "RootApproval" +msgstr "RootApproval" + +#: lib/RT/Date.pm:392 +msgid "Sat." +msgstr "Sab." + +#: html/Admin/Queues/People.html:104 +#: html/Ticket/Modify.html:38 +#: html/Ticket/ModifyAll.html:93 +#: html/Ticket/ModifyLinks.html:38 +#: html/Ticket/ModifyPeople.html:37 +msgid "Save Changes" +msgstr "Salva i Cambiamenti" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Save changes" +msgstr "Salva i cambiamenti" + +#. ($ARGS{'id'}) +#: html/Admin/Global/Scrip.html:48 +msgid "Scrip #%1" +msgstr "Scrip n°%1" + +#: lib/RT/Scrip_Overlay.pm:175 +msgid "Scrip Created" +msgstr "Scrip Created" + +#: html/Admin/Elements/EditScrips:83 +msgid "Scrip deleted" +msgstr "Scrip eliminato" + +#: html/Admin/Elements/QueueTabs:45 +#: html/Admin/Elements/SystemTabs:32 +#: html/Admin/Global/index.html:40 +msgid "Scrips" +msgstr "Scrips" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Scrips for %1\\n" +msgstr "Scrips per %1\\n" + +#: html/Admin/Queues/Scrips.html:32 +msgid "Scrips which apply to all queues" +msgstr "Scrips which apply to all code" + +#: html/Elements/SimpleSearch:26 +#: html/Search/Elements/PickRestriction:125 +#: html/Ticket/Elements/Tabs:158 +msgid "Search" +msgstr "Cerca" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Search Criteria" +msgstr "Crieri di Ricerca" + +#: html/Approvals/Elements/PendingMyApproval:38 +msgid "Search for approvals" +msgstr "Ricerca le richieste di approvazione" + +#: bin/rt-crontool:187 +msgid "Security:" +msgstr "Security:" + +#: lib/RT/Queue_Overlay.pm:66 +msgid "SeeQueue" +msgstr "VediCoda" + +#: html/Admin/Groups/index.html:39 +msgid "Select a group" +msgstr "Seleziona un gruppo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Select a queue" +msgstr "Seleziona una coda" + +#: html/Admin/Users/index.html:24 +#: html/Admin/Users/index.html:27 +msgid "Select a user" +msgstr "Seleziona un utente" + +#: html/Admin/Global/CustomField.html:37 +#: html/Admin/Global/CustomFields.html:35 +msgid "Select custom field" +msgstr "Seleziona un campo personalizzato" + +#: html/Admin/Elements/GroupTabs:51 +#: html/User/Elements/GroupTabs:49 +msgid "Select group" +msgstr "Seleziona gruppo" + +#: lib/RT/CustomField_Overlay.pm:421 +msgid "Select multiple values" +msgstr "Seleziona valori multipli" + +#: lib/RT/CustomField_Overlay.pm:418 +msgid "Select one value" +msgstr "Seleziona un volore solo" + +#: html/Admin/Elements/QueueTabs:66 +msgid "Select queue" +msgstr "Seleziona una coda" + +#: html/Admin/Global/Scrip.html:36 +#: html/Admin/Global/Scrips.html:35 +#: html/Admin/Queues/Scrip.html:39 +#: html/Admin/Queues/Scrips.html:49 +msgid "Select scrip" +msgstr "Seleziona uno scrip" + +#: html/Admin/Global/Template.html:56 +#: html/Admin/Global/Templates.html:35 +#: html/Admin/Queues/Template.html:54 +#: html/Admin/Queues/Templates.html:46 +msgid "Select template" +msgstr "Seleziona un modello" + +#: html/Admin/Elements/UserTabs:48 +msgid "Select user" +msgstr "Seleziona utente" + +#: lib/RT/CustomField_Overlay.pm:35 +msgid "SelectMultiple" +msgstr "SelectMultiple" + +#: lib/RT/CustomField_Overlay.pm:34 +msgid "SelectSingle" +msgstr "SelectSingle" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Self Service" +msgstr "Self Service" + +#: etc/initialdata:114 +msgid "Send mail to all watchers" +msgstr "Invia una mail a tutti gli osservatori" + +#: etc/initialdata:110 +msgid "Send mail to all watchers as a \"comment\"" +msgstr "Invia una mail atutti gli osservatori come un \"commento\"" + +#: etc/initialdata:105 +msgid "Send mail to requestors and Ccs" +msgstr "Invia mail ai richiedenti e Ccs" + +#: etc/initialdata:100 +msgid "Send mail to requestors and Ccs as a comment" +msgstr "Invia mail ai richiedenti e Ccs come commento" + +#: etc/initialdata:79 +msgid "Sends a message to the requestors" +msgstr "Invia un messaggio ai richiedenti" + +#: etc/initialdata:118 +#: etc/initialdata:122 +msgid "Sends mail to explicitly listed Ccs and Bccs" +msgstr "Sends mail to explicitly listed Ccs and Bccs" + +#: etc/initialdata:95 +msgid "Sends mail to the administrative Ccs" +msgstr "Sends mail to the administrative Ccs" + +#: etc/initialdata:91 +msgid "Sends mail to the administrative Ccs as a comment" +msgstr "Sends mail to the administrative Ccs as a comment" + +#: etc/initialdata:83 +#: etc/initialdata:87 +msgid "Sends mail to the owner" +msgstr "Sends mail to the owner" + +#: lib/RT/Date.pm:418 +msgid "Sep." +msgstr "Sep." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "September" +msgstr "September" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Show Results" +msgstr "Mostra i Risultati" + +#: html/Approvals/Elements/PendingMyApproval:43 +msgid "Show approved requests" +msgstr "Mostra le richieste approvate" + +#: html/Ticket/Create.html:143 +#: html/Ticket/Create.html:33 +msgid "Show basics" +msgstr "Mostra info di base" + +#: html/Approvals/Elements/PendingMyApproval:44 +msgid "Show denied requests" +msgstr "Mostra le richieste negate" + +#: html/Ticket/Create.html:143 +#: html/Ticket/Create.html:33 +msgid "Show details" +msgstr "Mostra i dettagli" + +#: html/Approvals/Elements/PendingMyApproval:42 +msgid "Show pending requests" +msgstr "Mostra le richieste in attesa" + +#: html/Approvals/Elements/PendingMyApproval:45 +msgid "Show requests awaiting other approvals" +msgstr "Mostra le richieste in attesa di altre approvazioni" + +#: lib/RT/Queue_Overlay.pm:80 +msgid "Show ticket private commentary" +msgstr "Show ticket private commentary" + +#: lib/RT/Queue_Overlay.pm:78 +msgid "Show ticket summaries" +msgstr "Show ticket summaries" + +#: lib/RT/Queue_Overlay.pm:68 +msgid "ShowACL" +msgstr "MostraLCA" + +#: lib/RT/Queue_Overlay.pm:77 +msgid "ShowScrips" +msgstr "MostraScrips" + +#: lib/RT/Queue_Overlay.pm:74 +msgid "ShowTemplate" +msgstr "MostraModello" + +#: lib/RT/Queue_Overlay.pm:78 +msgid "ShowTicket" +msgstr "MostraTicket" + +#: lib/RT/Queue_Overlay.pm:80 +msgid "ShowTicketComments" +msgstr "MostraICommentiAlTicket" + +#: lib/RT/Queue_Overlay.pm:81 +msgid "Sign up as a ticket Requestor or ticket or queue Cc" +msgstr "Sign up as a ticket Requestor or ticket or coda Cc" + +#: lib/RT/Queue_Overlay.pm:82 +msgid "Sign up as a ticket or queue AdminCc" +msgstr "Sign up as a ticket or coda AdminCc" + +#: html/Admin/Elements/ModifyUser:38 +#: html/Admin/Users/Modify.html:190 +#: html/Admin/Users/Prefs.html:31 +#: html/User/Prefs.html:111 +msgid "Signature" +msgstr "Firma" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Signed in as %1" +msgstr "Signed in as %1" + +#: html/Admin/Elements/SelectSingleOrMultiple:25 +msgid "Single" +msgstr "Single" + +#: html/Elements/Header:50 +msgid "Skip Menu" +msgstr "Skip Menu" + +#: html/Admin/Elements/AddCustomFieldValue:27 +msgid "Sort" +msgstr "Ordina" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Sort key" +msgstr "Sort key" + +#: html/Search/Elements/PickRestriction:108 +msgid "Sort results by" +msgstr "Ordina i risultati per" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "SortOrder" +msgstr "SortOrder" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Stalled" +msgstr "In stallo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Start page" +msgstr "Pagina iniziale" + +#: html/Elements/SelectDateType:26 +#: html/Ticket/Elements/EditDates:31 +#: html/Ticket/Elements/ShowDates:34 +msgid "Started" +msgstr "Iniziato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Started date '%1' could not be parsed" +msgstr "Started date '%1' could not be parsed" + +#: html/Elements/SelectDateType:30 +#: html/Ticket/Create.html:165 +#: html/Ticket/Elements/EditDates:26 +#: html/Ticket/Elements/ShowDates:30 +msgid "Starts" +msgstr "Inizia" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Starts By" +msgstr "Inizia Da" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Starts date '%1' could not be parsed" +msgstr "Starts date '%1' could not be parsed" + +#: html/Admin/Elements/ModifyUser:81 +#: html/Admin/Users/Modify.html:137 +#: html/User/Prefs.html:93 +msgid "State" +msgstr "Provincia" + +#: html/Elements/MyRequests:30 +#: html/Elements/MyTickets:30 +#: html/Search/Elements/PickRestriction:73 +#: html/SelfService/Elements/MyRequests:28 +#: html/SelfService/Update.html:30 +#: html/Ticket/Create.html:41 +#: html/Ticket/Elements/EditBasics:37 +#: html/Ticket/Elements/ShowBasics:30 +#: html/Ticket/Update.html:59 +#: lib/RT/Ticket_Overlay.pm:1163 +#: lib/RT/Tickets_Overlay.pm:907 +msgid "Status" +msgstr "Stato" + +#: etc/initialdata:294 +msgid "Status Change" +msgstr "Cambiamento di Stato" + +#. ($self->loc($self->OldValue), $self->loc($self->NewValue)) +#: lib/RT/Transaction_Overlay.pm:527 +msgid "Status changed from %1 to %2" +msgstr "Cambiato lo Stato da %1 a %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "StatusChange" +msgstr "StatusChange" + +#: html/Ticket/Elements/Tabs:146 +msgid "Steal" +msgstr "Ruba" + +#. ($Old->Name) +#: lib/RT/Transaction_Overlay.pm:586 +msgid "Stolen from %1 " +msgstr "Rubato da %1 " + +#: html/Elements/MyRequests:28 +#: html/Elements/MyTickets:28 +#: html/Search/Bulk.html:125 +#: html/Search/Elements/PickRestriction:42 +#: html/SelfService/Create.html:56 +#: html/SelfService/Elements/MyRequests:27 +#: html/SelfService/Update.html:31 +#: html/Ticket/Create.html:83 +#: html/Ticket/Elements/EditBasics:27 +#: html/Ticket/ModifyAll.html:78 +#: html/Ticket/Update.html:76 +#: lib/RT/Ticket_Overlay.pm:1159 +#: lib/RT/Tickets_Overlay.pm:986 +msgid "Subject" +msgstr "Oggetto" + +#. ($self->Data) +#: docs/design_docs/string-extraction-guide.txt:89 +#: lib/RT/Transaction_Overlay.pm:608 +msgid "Subject changed to %1" +msgstr "Subject changed to %1" + +#: html/Elements/Submit:58 +msgid "Submit" +msgstr "Invia" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Submit Workflow" +msgstr "Submit Workflow" + +#: lib/RT/Group_Overlay.pm:748 +msgid "Succeeded" +msgstr "Succeeded" + +#: lib/RT/Date.pm:393 +msgid "Sun." +msgstr "Dom." + +#: lib/RT/System.pm:53 +msgid "SuperUser" +msgstr "SuperUtente" + +#: html/User/Elements/DelegateRights:76 +msgid "System" +msgstr "Sistema" + +#: html/Admin/Elements/SelectRights:80 +#: lib/RT/ACE_Overlay.pm:566 +#: lib/RT/Interface/Web.pm:790 +#: lib/RT/Interface/Web.pm:823 +msgid "System Error" +msgstr "Errore di Sistema" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "System Error. Right not granted." +msgstr "Errore di Sistema. Diritto non concesso." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "System Error. right not granted" +msgstr "Errore di Sistema. Diritto non concesso" + +#: lib/RT/ACE_Overlay.pm:615 +msgid "System error. Right not delegated." +msgstr "Errore di Sistema. Diritto non delegato." + +#: lib/RT/ACE_Overlay.pm:145 +#: lib/RT/ACE_Overlay.pm:222 +#: lib/RT/ACE_Overlay.pm:305 +#: lib/RT/ACE_Overlay.pm:897 +msgid "System error. Right not granted." +msgstr "Errore di Sistema. Diritto non concesso." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "System error. Unable to grant rights." +msgstr "Errore di sistema. Impossibile concedere i diritti." + +#: html/Admin/Global/GroupRights.html:34 +#: html/Admin/Groups/GroupRights.html:36 +#: html/Admin/Queues/GroupRights.html:35 +msgid "System groups" +msgstr "Gruppi di sistema" + +#: etc/initialdata:41 +#: etc/initialdata:47 +#: etc/initialdata:53 +msgid "SystemRolegroup for internal use" +msgstr "SystemRolegroup for internal use" + +#: lib/RT/CurrentUser.pm:317 +msgid "TEST_STRING" +msgstr "TEST_STRING" + +#: html/Ticket/Elements/Tabs:142 +msgid "Take" +msgstr "Prendi" + +#: lib/RT/Transaction_Overlay.pm:572 +msgid "Taken" +msgstr "Preso" + +#: html/Admin/Elements/EditScrip:80 +msgid "Template" +msgstr "Modello" + +#. ($TemplateObj->Id()) +#: html/Admin/Global/Template.html:90 +#: html/Admin/Queues/Template.html:89 +msgid "Template #%1" +msgstr "Modello n°%1" + +#: html/Admin/Elements/EditTemplates:88 +msgid "Template deleted" +msgstr "Modello eliminato" + +#: lib/RT/Scrip_Overlay.pm:152 +msgid "Template not found" +msgstr "Modello non trovato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Template not found\\n" +msgstr "Modello non trovato\\n" + +#: lib/RT/Template_Overlay.pm:346 +msgid "Template parsed" +msgstr "Modello elaborato" + +#: html/Admin/Elements/QueueTabs:48 +#: html/Admin/Elements/SystemTabs:35 +#: html/Admin/Global/index.html:44 +msgid "Templates" +msgstr "Modelli" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Templates for %1\\n" +msgstr "Modelli per %1\\n" + +#: lib/RT/Interface/Web.pm:891 +msgid "That is already the current value" +msgstr "That is already the current value" + +#: lib/RT/CustomField_Overlay.pm:242 +msgid "That is not a value for this custom field" +msgstr "That is not a value for this custom field" + +#: lib/RT/Ticket_Overlay.pm:1885 +msgid "That is the same value" +msgstr "That is the same value" + +#: lib/RT/ACE_Overlay.pm:287 +#: lib/RT/ACE_Overlay.pm:596 +msgid "That principal already has that right" +msgstr "That principal already has that right" + +#. ($args{'Type'}) +#: lib/RT/Queue_Overlay.pm:632 +msgid "That principal is already a %1 for this queue" +msgstr "That principal is already a %1 for this coda" + +#. ($self->loc($args{'Type'})) +#: lib/RT/Ticket_Overlay.pm:1433 +msgid "That principal is already a %1 for this ticket" +msgstr "That principal is already a %1 for this ticket" + +#. ($args{'Type'}) +#: lib/RT/Queue_Overlay.pm:731 +msgid "That principal is not a %1 for this queue" +msgstr "That principal is not a %1 for this coda" + +#. ($args{'Type'}) +#: lib/RT/Ticket_Overlay.pm:1550 +msgid "That principal is not a %1 for this ticket" +msgstr "That principal is not a %1 for this ticket" + +#: lib/RT/Ticket_Overlay.pm:1881 +msgid "That queue does not exist" +msgstr "That coda does not exist" + +#: lib/RT/Ticket_Overlay.pm:3209 +msgid "That ticket has unresolved dependencies" +msgstr "That ticket has unresolved dependencies" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "That user already has that right" +msgstr "That user already has that right" + +#: lib/RT/Ticket_Overlay.pm:3019 +msgid "That user already owns that ticket" +msgstr "That user already owns that ticket" + +#: lib/RT/Ticket_Overlay.pm:2985 +msgid "That user does not exist" +msgstr "That user does not exist" + +#: lib/RT/User_Overlay.pm:314 +msgid "That user is already privileged" +msgstr "Questo utente è già previlegiato" + +#: lib/RT/User_Overlay.pm:335 +msgid "That user is already unprivileged" +msgstr "Questo utente è già non previlegiato" + +#: lib/RT/User_Overlay.pm:327 +msgid "That user is now privileged" +msgstr "Ora questo utente è previlegiato" + +#: lib/RT/User_Overlay.pm:348 +msgid "That user is now unprivileged" +msgstr "Ora questo utente è non previlegiato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "That user is now unprivilegedileged" +msgstr "Questo utente ora è non previlegiato" + +#: lib/RT/Ticket_Overlay.pm:3011 +msgid "That user may not own tickets in that queue" +msgstr "That user may not own tickets in that coda" + +#: lib/RT/Link_Overlay.pm:205 +msgid "That's not a numerical id" +msgstr "That's not a numerical id" + +#: html/SelfService/Display.html:31 +#: html/Ticket/Create.html:149 +#: html/Ticket/Elements/ShowSummary:27 +msgid "The Basics" +msgstr "Dati di base" + +#: lib/RT/ACE_Overlay.pm:87 +msgid "The CC of a ticket" +msgstr "The CC of a ticket" + +#: lib/RT/ACE_Overlay.pm:88 +msgid "The administrative CC of a ticket" +msgstr "The administrative CC of a ticket" + +#: lib/RT/Ticket_Overlay.pm:2212 +msgid "The comment has been recorded" +msgstr "The comment has been recorded" + +#: bin/rt-crontool:197 +msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:" +msgstr "The following command will find all active tickets in the coda 'general' and set their priority to 99 if they haven't been touched in 4 hours:" + +#: bin/rt-commit-handler:755 +#: bin/rt-commit-handler:765 +msgid "" +"The following commands were not proccessed:\\n" +"\\n" +msgstr "" +"The following commands were not proccessed:\\n" +"\\n" + +#: lib/RT/Interface/Web.pm:894 +msgid "The new value has been set." +msgstr "The new value has been set." + +#: lib/RT/ACE_Overlay.pm:85 +msgid "The owner of a ticket" +msgstr "The owner of a ticket" + +#: lib/RT/ACE_Overlay.pm:86 +msgid "The requestor of a ticket" +msgstr "Il richiedente di un ticket" + +#: html/Admin/Elements/EditUserComments:25 +msgid "These comments aren't generally visible to the user" +msgstr "These comments aren't generally visible to the user" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "This ticket %1 %2 (%3)\\n" +msgstr "This ticket %1 %2 (%3)\\n" + +#: bin/rt-crontool:188 +msgid "This tool allows the user to run arbitrary perl modules from within RT." +msgstr "This tool allows the user to run arbitrary perl modules from within RT." + +#: lib/RT/Transaction_Overlay.pm:250 +msgid "This transaction appears to have no content" +msgstr "This transaction appears to have no content" + +#. ($rows) +#: html/Ticket/Elements/ShowRequestor:46 +msgid "This user's %1 highest priority tickets" +msgstr "I %1 tickets di questo utente a più alta priorità " + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "This user's 25 highest priority tickets" +msgstr "I 25 tickets a più alta priorità di questo utente" + +#: lib/RT/Date.pm:390 +msgid "Thu." +msgstr "Gio." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket" +msgstr "" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket # %1 %2" +msgstr "Ticket n° %1 %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket # %1 Jumbo update: %2" +msgstr "Ticket n° %1 aggiornamento Jumbo: %2" + +#. ($Ticket->Id, $Ticket->Subject) +#: html/Ticket/ModifyAll.html:24 +#: html/Ticket/ModifyAll.html:28 +msgid "Ticket #%1 Jumbo update: %2" +msgstr "Ticket n° %1 Jumbo update: %2" + +#. ($link->BaseObj->Id, $link->BaseObj->Subject) +#: html/Approvals/Elements/ShowDependency:45 +msgid "Ticket #%1: %2" +msgstr "Ticket n°%1: %2" + +#. ($self->Id, $QueueObj->Name) +#: lib/RT/Ticket_Overlay.pm:586 +#: lib/RT/Ticket_Overlay.pm:607 +msgid "Ticket %1 created in queue '%2'" +msgstr "Ticket %1 created in coda '%2'" + +#. ($Ticket->Id) +#: bin/rt-commit-handler:759 +msgid "Ticket %1 loaded\\n" +msgstr "Ticket %1 loaded\\n" + +#. ($Ticket->Id,$_) +#: html/Search/Bulk.html:180 +msgid "Ticket %1: %2" +msgstr "Ticket %1: %2" + +#. ($Ticket->Id, $Ticket->Subject) +#: html/Ticket/History.html:24 +#: html/Ticket/History.html:27 +msgid "Ticket History # %1 %2" +msgstr "Ticket History n° %1 %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket Id" +msgstr "Ticket Id" + +#: etc/initialdata:309 +msgid "Ticket Resolved" +msgstr "Ticket Risolto" + +#: html/Search/Elements/PickRestriction:62 +msgid "Ticket attachment" +msgstr "Allegato al ticket: il " + +#: lib/RT/Tickets_Overlay.pm:1165 +msgid "Ticket content" +msgstr "Contenuto del ticket" + +#: lib/RT/Tickets_Overlay.pm:1211 +msgid "Ticket content type" +msgstr "Ticket content type" + +#: lib/RT/Ticket_Overlay.pm:495 +#: lib/RT/Ticket_Overlay.pm:596 +msgid "Ticket could not be created due to an internal error" +msgstr "Ticket could not be created due to an internal error" + +#: lib/RT/Transaction_Overlay.pm:519 +msgid "Ticket created" +msgstr "Ticket creato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket creation failed" +msgstr "Ticket creation failed" + +#: lib/RT/Transaction_Overlay.pm:524 +msgid "Ticket deleted" +msgstr "Ticket eliminato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket id not found" +msgstr "Ticket id not found" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket killed" +msgstr "Ticket killed" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Ticket not found" +msgstr "Ticket not found" + +#: etc/initialdata:295 +msgid "Ticket status changed" +msgstr "Ticket status changed" + +#: html/Ticket/Update.html:38 +msgid "Ticket watchers" +msgstr "Osservatori del ticket" + +#: html/Elements/Tabs:46 +msgid "Tickets" +msgstr "" + +#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'})) +#: lib/RT/Tickets_Overlay.pm:1382 +msgid "Tickets %1 %2" +msgstr "" + +#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'})) +#: lib/RT/Tickets_Overlay.pm:1347 +msgid "Tickets %1 by %2" +msgstr "Tickets %1 by %2" + +#. ($name) +#: html/Elements/ViewUser:25 +msgid "Tickets from %1" +msgstr "Tickets from %1" + +#: html/Approvals/Elements/ShowDependency:26 +msgid "Tickets which depend on this approval:" +msgstr "Tickets which depend on this approval:" + +#: html/Ticket/Create.html:156 +#: html/Ticket/Elements/EditBasics:47 +msgid "Time Left" +msgstr "Tempo RImasto" + +#: html/Ticket/Create.html:155 +#: html/Ticket/Elements/EditBasics:42 +msgid "Time Worked" +msgstr "Tempo Lavorato" + +#: lib/RT/Tickets_Overlay.pm:1138 +msgid "Time left" +msgstr "Tempo rimasto" + +#: html/Elements/Footer:35 +msgid "Time to display" +msgstr "Time to display" + +#: lib/RT/Tickets_Overlay.pm:1114 +msgid "Time worked" +msgstr "Tempo lavorato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "TimeLeft" +msgstr "TempoRimasto" + +#: lib/RT/Ticket_Overlay.pm:1164 +msgid "TimeWorked" +msgstr "TempoLavorato" + +#: bin/rt-commit-handler:401 +msgid "To generate a diff of this commit:" +msgstr "To generate a diff of this commit:" + +#: bin/rt-commit-handler:390 +msgid "To generate a diff of this commit:\\n" +msgstr "To generate a diff of this commit:\\n" + +#: lib/RT/Ticket_Overlay.pm:1167 +msgid "Told" +msgstr "Told" + +#: etc/initialdata:237 +msgid "Transaction" +msgstr "Transaction" + +#. ($self->Data) +#: lib/RT/Transaction_Overlay.pm:639 +msgid "Transaction %1 purged" +msgstr "Transaction %1 purged" + +#: lib/RT/Transaction_Overlay.pm:176 +msgid "Transaction Created" +msgstr "Transaction Created" + +#: lib/RT/Transaction_Overlay.pm:88 +msgid "Transaction->Create couldn't, as you didn't specify a ticket id" +msgstr "Transaction->Create couldn't, as you didn't specify a ticket id" + +#: lib/RT/Transaction_Overlay.pm:698 +msgid "Transactions are immutable" +msgstr "Transactions are immutable" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Trying to delete a right: %1" +msgstr "Sto cercando di eliminare un diritto: %1" + +#: lib/RT/Date.pm:388 +msgid "Tue." +msgstr "Mar." + +#: html/Admin/Elements/EditCustomField:43 +#: html/Ticket/Elements/AddWatchers:32 +#: html/Ticket/Elements/AddWatchers:43 +#: html/Ticket/Elements/AddWatchers:53 +#: lib/RT/Ticket_Overlay.pm:1165 +#: lib/RT/Tickets_Overlay.pm:958 +msgid "Type" +msgstr "Type" + +#: lib/RT/ScripCondition_Overlay.pm:103 +msgid "Unimplemented" +msgstr "Unimplemented" + +#: html/Admin/Users/Modify.html:67 +msgid "Unix login" +msgstr "Unix login" + +#: html/Admin/Elements/ModifyUser:61 +msgid "UnixUsername" +msgstr "UnixUsername" + +#. ($self->ContentEncoding) +#: lib/RT/Attachment_Overlay.pm:264 +msgid "Unknown ContentEncoding %1" +msgstr "Unknown ContentEncoding %1" + +#: html/Elements/SelectResultsPerPage:36 +msgid "Unlimited" +msgstr "Unlimited" + +#: etc/initialdata:32 +msgid "Unprivileged" +msgstr "Non previlegiato" + +#: lib/RT/Transaction_Overlay.pm:568 +msgid "Untaken" +msgstr "Untaken" + +#: html/Elements/MyTickets:63 +#: html/Search/Bulk.html:32 +msgid "Update" +msgstr "Aggiornamento" + +#: html/Admin/Users/Prefs.html:61 +msgid "Update ID" +msgstr "ID Aggiornamento" + +#: html/Search/Bulk.html:119 +#: html/Ticket/ModifyAll.html:65 +#: html/Ticket/Update.html:66 +msgid "Update Type" +msgstr "Tipo Aggiornamento" + +#: html/Search/Listing.html:60 +msgid "Update all these tickets at once" +msgstr "Aggiorna tutti questi tickets in una sola volta" + +#: html/Admin/Users/Prefs.html:48 +msgid "Update email" +msgstr "Email aggiornamento" + +#: html/Admin/Users/Prefs.html:54 +msgid "Update name" +msgstr "Nome aggiornamento" + +#: lib/RT/Interface/Web.pm:408 +msgid "Update not recorded." +msgstr "Aggiornamento non registrato." + +#: html/Search/Bulk.html:80 +msgid "Update selected tickets" +msgstr "Aggiorna i tickets selezionati" + +#: html/Admin/Users/Prefs.html:35 +msgid "Update signature" +msgstr "Aggiorna la firma" + +#: html/Ticket/ModifyAll.html:62 +msgid "Update ticket" +msgstr "Aggiorna il ticket" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Update ticket # %1" +msgstr "Aggiorna il ticket n° %1" + +#. ($Ticket->id) +#: html/SelfService/Update.html:24 +#: html/SelfService/Update.html:46 +msgid "Update ticket #%1" +msgstr "Aggiorna il ticket n°%1" + +#. ($Ticket->id, $Ticket->Subject) +#: html/Ticket/Update.html:134 +msgid "Update ticket #%1 (%2)" +msgstr "Aggiorna il ticket n°%1 (%2)" + +#: lib/RT/Interface/Web.pm:406 +msgid "Update type was neither correspondence nor comment." +msgstr "Update type was neither correspondence nor comment." + +#: html/Elements/SelectDateType:32 +#: html/Ticket/Elements/ShowDates:50 +#: lib/RT/Ticket_Overlay.pm:1168 +msgid "Updated" +msgstr "Aggiornato" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "User %1 %2: %3\\n" +msgstr "User %1 %2: %3\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "User %1 Password: %2\\n" +msgstr "User %1 Password: %2\\n" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "User '%1' not found" +msgstr "User '%1' not found" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "User '%1' not found\\n" +msgstr "User '%1' not found\\n" + +#: etc/initialdata:125 +#: etc/initialdata:191 +msgid "User Defined" +msgstr "Definito da Utente" + +#: html/Admin/Users/Prefs.html:58 +msgid "User ID" +msgstr "User ID" + +#: html/Elements/SelectUsers:25 +msgid "User Id" +msgstr "User Id" + +#: html/Admin/Elements/GroupTabs:46 +#: html/Admin/Elements/QueueTabs:59 +#: html/Admin/Elements/SystemTabs:46 +#: html/Admin/Global/index.html:58 +msgid "User Rights" +msgstr "Diritti Utente" + +#. ($msg) +#: html/Admin/Users/Modify.html:225 +msgid "User could not be created: %1" +msgstr "User could not be created: %1" + +#: lib/RT/User_Overlay.pm:261 +msgid "User created" +msgstr "User created" + +#: html/Admin/Global/GroupRights.html:66 +#: html/Admin/Groups/GroupRights.html:53 +#: html/Admin/Queues/GroupRights.html:67 +msgid "User defined groups" +msgstr "Gruppi definiti dall'utente" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "User notified" +msgstr "User notified" + +#: html/Admin/Users/Prefs.html:24 +#: html/Admin/Users/Prefs.html:28 +msgid "User view" +msgstr "User view" + +#: html/Admin/Users/Modify.html:47 +#: html/Elements/Login:50 +#: html/Ticket/Elements/AddWatchers:34 +msgid "Username" +msgstr "Username" + +#: html/Admin/Elements/SelectNewGroupMembers:25 +#: html/Admin/Elements/Tabs:31 +#: html/Admin/Groups/Members.html:54 +#: html/Admin/Queues/People.html:67 +#: html/Admin/index.html:28 +#: html/User/Groups/Members.html:57 +msgid "Users" +msgstr "Utenti" + +#: html/Admin/Users/index.html:64 +msgid "Users matching search criteria" +msgstr "Utenti che soddisfano il criterio di ricerca" + +#: html/Search/Elements/PickRestriction:50 +msgid "ValueOfQueue" +msgstr "ValueOfQueue" + +#: html/Admin/Elements/EditCustomField:56 +msgid "Values" +msgstr "Valori" + +#: lib/RT/Queue_Overlay.pm:81 +msgid "Watch" +msgstr "Osserva" + +#: lib/RT/Queue_Overlay.pm:82 +msgid "WatchAsAdminCc" +msgstr "OsservaComeAdminCc" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Watcher loaded" +msgstr "Osservatore caricato" + +#: html/Admin/Elements/QueueTabs:41 +msgid "Watchers" +msgstr "Osservatori" + +#: html/Admin/Elements/ModifyUser:55 +msgid "WebEncoding" +msgstr "WebEncoding" + +#: lib/RT/Date.pm:389 +msgid "Wed." +msgstr "Mer." + +#: etc/upgrade/2.1.71:161 +msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket" +msgstr "When a ticket has been approved by all approvers, add correspondence to the original ticket" + +#: etc/upgrade/2.1.71:135 +msgid "When a ticket has been approved by any approver, add correspondence to the original ticket" +msgstr "When a ticket has been approved by any approver, add correspondence to the original ticket" + +#: etc/initialdata:138 +msgid "When a ticket is created" +msgstr "When a ticket is created" + +#: etc/upgrade/2.1.71:79 +msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval" +msgstr "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval" + +#: etc/initialdata:143 +msgid "When anything happens" +msgstr "When anything happens" + +#: etc/initialdata:184 +msgid "Whenever a ticket is resolved" +msgstr "Whenever a ticket is resolved" + +#: etc/initialdata:170 +msgid "Whenever a ticket's owner changes" +msgstr "Whenever a ticket's owner changes" + +#: etc/initialdata:178 +msgid "Whenever a ticket's queue changes" +msgstr "Whenever a ticket's coda changes" + +#: etc/initialdata:162 +msgid "Whenever a ticket's status changes" +msgstr "Whenever a ticket's status changes" + +#: etc/initialdata:192 +msgid "Whenever a user-defined condition occurs" +msgstr "Whenever a user-defined condition occurs" + +#: etc/initialdata:156 +msgid "Whenever comments come in" +msgstr "Whenever comments come in" + +#: etc/initialdata:149 +msgid "Whenever correspondence comes in" +msgstr "Whenever correspondence comes in" + +#: html/Admin/Users/Modify.html:163 +#: html/User/Prefs.html:51 +msgid "Work" +msgstr "Lavoro" + +#: html/Admin/Elements/ModifyUser:69 +msgid "WorkPhone" +msgstr "TelefonoLavoro" + +#: html/Ticket/Elements/ShowBasics:34 +#: html/Ticket/Update.html:64 +msgid "Worked" +msgstr "Lavoro" + +#: lib/RT/Ticket_Overlay.pm:3122 +msgid "You already own this ticket" +msgstr "You already own this ticket" + +#: html/autohandler:107 +msgid "You are not an authorized user" +msgstr "You are not an authorized user" + +#: lib/RT/Ticket_Overlay.pm:2997 +msgid "You can only reassign tickets that you own or that are unowned" +msgstr "You can only reassign tickets that you own or that are unowned" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "You don't have permission to view that ticket.\\n" +msgstr "Non hai i permessi per visualizzare questo ticket.\\n" + +#. ($num, $queue) +#: docs/design_docs/string-extraction-guide.txt:47 +msgid "You found %1 tickets in queue %2" +msgstr "Hai trovato %1 tickets nella coda %2" + +#: html/NoAuth/Logout.html:30 +msgid "You have been logged out of RT." +msgstr "Ti sei scollegato da RT." + +#: html/SelfService/Display.html:77 +msgid "You have no permission to create tickets in that queue." +msgstr "Non hai permessi per creare tickets in questa coda." + +#: lib/RT/Ticket_Overlay.pm:1894 +msgid "You may not create requests in that queue." +msgstr "Non puoi creare richieste in questa coda." + +#: html/NoAuth/Logout.html:35 +msgid "You're welcome to login again" +msgstr "Collegati di nuovo" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Your %1 requests" +msgstr "Le tue %1 richieste" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Your RT administrator has misconfigured the mail aliases which invoke RT" +msgstr "Your RT administrator has misconfigured the mail aliases which invoke RT" + +#: etc/initialdata:435 +#: etc/upgrade/2.1.71:146 +msgid "Your request has been approved by %1. Other approvals may still be pending." +msgstr "Your request has been approved by %1. Other approvals may still be pending." + +#: etc/initialdata:469 +#: etc/upgrade/2.1.71:180 +msgid "Your request has been approved." +msgstr "Your request has been approved." + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "Your request was rejected" +msgstr "Your request was rejected" + +#: etc/initialdata:390 +#: etc/upgrade/2.1.71:101 +msgid "Your request was rejected." +msgstr "Your request was rejected." + +#: html/autohandler:126 +msgid "Your username or password is incorrect" +msgstr "Il tuo username o la tua password non sono corretti" + +#: html/Admin/Elements/ModifyUser:83 +#: html/Admin/Users/Modify.html:143 +#: html/User/Prefs.html:95 +msgid "Zip" +msgstr "CAP" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "[no subject]" +msgstr "[nessun oggetto]" + +#. ($right->PrincipalObj->Object->SelfDescription) +#: html/User/Elements/DelegateRights:58 +msgid "as granted to %1" +msgstr "come concesso a %1" + +#: html/SelfService/Closed.html:27 +msgid "closed" +msgstr "chiuso" + +#: html/Elements/SelectCustomFieldOperator:37 +#: html/Elements/SelectMatch:33 +msgid "contains" +msgstr "contiene" + +#: html/Elements/SelectAttachmentField:25 +msgid "content" +msgstr "contenuto" + +#: html/Elements/SelectAttachmentField:26 +msgid "content-type" +msgstr "content-type" + +#: lib/RT/Ticket_Overlay.pm:2281 +msgid "correspondence (probably) not sent" +msgstr "corrispondenza (probabilmente) non inviata" + +#: lib/RT/Ticket_Overlay.pm:2291 +msgid "correspondence sent" +msgstr "corrispondenza inviata" + +#: html/Admin/Elements/ModifyQueue:62 +#: html/Admin/Queues/Modify.html:76 +#: lib/RT/Date.pm:318 +msgid "days" +msgstr "giorni" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "dead" +msgstr "morto" + +#: html/Search/Listing.html:74 +msgid "delete" +msgstr "elimina" + +#: lib/RT/Queue_Overlay.pm:62 +msgid "deleted" +msgstr "eliminato" + +#: html/Search/Elements/PickRestriction:67 +msgid "does not match" +msgstr "non corrisponde a" + +#: html/Elements/SelectCustomFieldOperator:37 +#: html/Elements/SelectMatch:34 +msgid "doesn't contain" +msgstr "non contiene" + +#: html/Elements/SelectEqualityOperator:37 +msgid "equal to" +msgstr "uguale a" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "false" +msgstr "falso" + +#: html/Elements/SelectAttachmentField:27 +msgid "filename" +msgstr "nome file" + +#: html/Elements/SelectCustomFieldOperator:37 +#: html/Elements/SelectEqualityOperator:37 +msgid "greater than" +msgstr "più grande di" + +#. ($self->Name) +#: lib/RT/Group_Overlay.pm:193 +msgid "group '%1'" +msgstr "gruppo '%1'" + +#: lib/RT/Date.pm:314 +msgid "hours" +msgstr "ore" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "id" +msgstr "id" + +#: html/Elements/SelectBoolean:31 +#: html/Elements/SelectCustomFieldOperator:37 +#: html/Elements/SelectMatch:35 +#: html/Search/Elements/PickRestriction:46 +#: html/Search/Elements/PickRestriction:75 +#: html/Search/Elements/PickRestriction:87 +msgid "is" +msgstr "è" + +#: html/Elements/SelectBoolean:35 +#: html/Elements/SelectCustomFieldOperator:37 +#: html/Elements/SelectMatch:36 +#: html/Search/Elements/PickRestriction:47 +#: html/Search/Elements/PickRestriction:76 +#: html/Search/Elements/PickRestriction:88 +msgid "isn't" +msgstr "non è" + +#: html/Elements/SelectCustomFieldOperator:37 +#: html/Elements/SelectEqualityOperator:37 +msgid "less than" +msgstr "minore di" + +#: html/Search/Elements/PickRestriction:66 +msgid "matches" +msgstr "corrisponde a" + +#: lib/RT/Date.pm:310 +msgid "min" +msgstr "min" + +#: html/Ticket/Update.html:65 +msgid "minutes" +msgstr "minuti" + +#: bin/rt-commit-handler:764 +msgid "" +"modifications\\n" +"\\n" +msgstr "" +"modifiche\\n" +"\\n" + +#: lib/RT/Date.pm:326 +msgid "months" +msgstr "mesi" + +#: lib/RT/Queue_Overlay.pm:57 +msgid "new" +msgstr "nuovo" + +#: html/Admin/Elements/EditScrips:42 +msgid "no value" +msgstr "nessun valore" + +#: html/Ticket/Elements/EditWatchers:27 +msgid "none" +msgstr "nessuno" + +#: html/Elements/SelectEqualityOperator:37 +msgid "not equal to" +msgstr "diverso da" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "notlike" +msgstr "diverso da" + +#: html/SelfService/Elements/MyRequests:60 +#: lib/RT/Queue_Overlay.pm:58 +msgid "open" +msgstr "aperto" + +#. ($self->Name, $user->Name) +#: lib/RT/Group_Overlay.pm:198 +msgid "personal group '%1' for user '%2'" +msgstr "Gruppo personale '%1' per l'utente '%2'" + +#. ($queue->Name, $self->Type) +#: lib/RT/Group_Overlay.pm:206 +msgid "queue %1 %2" +msgstr "coda %1 %2" + +#: lib/RT/Queue_Overlay.pm:61 +msgid "rejected" +msgstr "rifiutato" + +#: lib/RT/Queue_Overlay.pm:60 +msgid "resolved" +msgstr "risolto" + +#: lib/RT/Date.pm:306 +msgid "sec" +msgstr "sec" + +#: lib/RT/Queue_Overlay.pm:59 +msgid "stalled" +msgstr "in stallo" + +#. ($self->Type) +#: lib/RT/Group_Overlay.pm:201 +msgid "system %1" +msgstr "sistema %1" + +#. ($self->Type) +#: lib/RT/Group_Overlay.pm:212 +msgid "system group '%1'" +msgstr "gruppo di sistema '%1'" + +#: html/Elements/Error:41 +#: html/SelfService/Error.html:41 +msgid "the calling component did not specify why" +msgstr "the calling component did not specify why" + +#. ($self->Instance, $self->Type) +#: lib/RT/Group_Overlay.pm:209 +msgid "ticket #%1 %2" +msgstr "ticket n°%1 %2" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "true" +msgstr "vero" + +#. ($self->Id) +#: lib/RT/Group_Overlay.pm:215 +msgid "undescribed group %1" +msgstr "undescribed group %1" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "undescripbed group %1" +msgstr "undescripbed group %1" + +#. ($user->Object->Name) +#: lib/RT/Group_Overlay.pm:190 +msgid "user %1" +msgstr "utente %1" + +#: lib/RT/Date.pm:322 +msgid "weeks" +msgstr "settimane" + +#: NOT +#: FOUND +#: IN +#: SOURCE +msgid "with template %1" +msgstr "con il modello %1" + +#: lib/RT/Date.pm:330 +msgid "years" +msgstr "anni" + diff --git a/rt/lib/RT/I18N/ru.po b/rt/lib/RT/I18N/ru.po index eb1434606..d5ef7fd0c 100644 --- a/rt/lib/RT/I18N/ru.po +++ b/rt/lib/RT/I18N/ru.po @@ -62,10 +62,6 @@ msgstr "%1 %2 изменено на %3" msgid "%1 %2 deleted" msgstr "" -#: NOT FOUND IN SOURCE -msgid "%1 %2 of group %3" -msgstr "" - #: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28 #. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name)) msgid "%1 %2 with template %3" @@ -151,11 +147,7 @@ msgstr "%1 изменилоÑÑŒ Ñ %2 на %3" #: lib/RT/Interface/Web.pm:857 msgid "%1 could not be set to %2." -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "%1 couldn't init a transaction (%2)\\n" -msgstr "" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ ÑƒÑтановить %1 в %2." #: lib/RT/Ticket_Overlay.pm:2813 #. ($self) @@ -165,12 +157,12 @@ msgstr "%1 не могу закрыть тикет. Возможно, база Ð #: html/Elements/MyTickets:25 #. ($rows) msgid "%1 highest priority tickets I own..." -msgstr "" +msgstr "%1 Ñамых приоритетных моих тикетов..." #: html/Elements/MyRequests:25 #. ($rows) msgid "%1 highest priority tickets I requested..." -msgstr "" +msgstr "%1 Ñамых приоритетных тикетов, запрошенных мной..." #: bin/rt-crontool:161 #. ($0) @@ -192,10 +184,6 @@ msgstr "%1 больше не ÑвлÑетÑÑ %2 Ð´Ð»Ñ Ñтого тикета. msgid "%1 is no longer a value for custom field %2" msgstr "%1 больше не ÑвлÑетÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÐµÐ¼ Ð´Ð»Ñ Ð½ÐµÑтандартного Ð¿Ð¾Ð»Ñ %2" -#: NOT FOUND IN SOURCE -msgid "%1 isn't a valid Queue id." -msgstr "" - #: html/Ticket/Elements/ShowBasics:36 #. ($TimeWorked) msgid "%1 min" @@ -208,7 +196,7 @@ msgstr "%1 не отображаетÑÑ" #: html/User/Elements/DelegateRights:76 #. (loc($ObjectType =~ /^RT::(.*)$/)) msgid "%1 rights" -msgstr "" +msgstr "%1 права" #: NOT FOUND IN SOURCE msgid "%1 succeeded\\n" @@ -222,10 +210,6 @@ msgstr "%1 тип не извеÑтен Ð´Ð»Ñ $MessageId" msgid "%1 type unknown for %2" msgstr "%1 тип не извеÑтен Ð´Ð»Ñ %2" -#: NOT FOUND IN SOURCE -msgid "%1 was created without a CurrentUser\\n" -msgstr "" - #: lib/RT/Action/ResolveMembers.pm:42 #. (ref $self) msgid "%1 will resolve all members of a resolved group ticket." @@ -259,22 +243,11 @@ msgstr "'%1' ÑвлÑетÑÑ Ð½ÐµÐ²ÐµÑ€Ð½Ñ‹Ð¼ значением ÑтатуÑа msgid "'%1' not a recognized action. " msgstr "Что делать ? : '%1'" -#: NOT FOUND IN SOURCE -msgid "(Check box to delete group member)" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "(Check box to delete scrip)" -msgstr "" #: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55 msgid "(Check box to delete)" msgstr "(Пометьте то, что хотите удалить)" -#: NOT FOUND IN SOURCE -msgid "(Check boxes to delete)" -msgstr "" - #: html/Ticket/Create.html:178 msgid "(Enter ticket ids or URLs, seperated with spaces)" msgstr "(Введите номера или ÑÑылки на тикеты. ÐеÑколько тикетов разделÑÑŽÑ‚ÑÑ Ð¿Ñ€Ð¾Ð±ÐµÐ»Ð°Ð¼Ð¸.)" @@ -283,15 +256,11 @@ msgstr "(Введите номера или ÑÑылки на тикеты. Ðе #. ($RT::CorrespondAddress) #. ($RT::CommentAddress) msgid "(If left blank, will default to %1" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "(No Value)" -msgstr "" +msgstr "(ЕÑли пуÑтое, то по умолчанию равно %1" #: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32 msgid "(No custom fields)" -msgstr "" +msgstr "(Ðет дополнительных полей)" #: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53 msgid "(No members)" @@ -303,11 +272,11 @@ msgstr "(Ðет Ñкриптов)" #: html/Admin/Elements/EditTemplates:31 msgid "(No templates)" -msgstr "" +msgstr "(Ðет шаблонов)" #: html/Ticket/Update.html:85 msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)" -msgstr "" +msgstr "(Ðа Ñти адреÑа [разделенные запÑтой] отправлÑÑŽÑ‚ÑÑ ÐºÐ¾Ð¿Ð¸Ð¸ ÑообщениÑ. ÐдреÑа <b>не</b> ÑохранÑÑŽÑ‚ÑÑ Ð´Ð»Ñ Ð¿Ð¾Ñледующих уведомлений.)" #: NOT FOUND IN SOURCE msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)" @@ -315,11 +284,11 @@ msgstr "(Ðа Ñти адреÑа [разделенные запÑтой] отп #: html/Ticket/Create.html:79 msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)" -msgstr "" +msgstr "(Ðа Ñти адреÑа [разделенные запÑтой] отправлÑÑŽÑ‚ÑÑ ÐºÐ¾Ð¿Ð¸Ð¸ ÑообщениÑ. ÐдреÑа <b>ÑохранÑÑŽÑ‚ÑÑ</b> Ð´Ð»Ñ Ð¿Ð¾Ñледующих уведомлений.)" #: html/Ticket/Update.html:81 msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)" -msgstr "" +msgstr "(Ðа Ñти адреÑа [разделенные запÑтой] отправлÑÑŽÑ‚ÑÑ ÐºÐ¾Ð¿Ð¸Ð¸ ÑообщениÑ. ÐдреÑа <b>не</b> ÑохранÑÑŽÑ‚ÑÑ Ð´Ð»Ñ Ð¿Ð¾Ñледующих уведомлений.)" #: NOT FOUND IN SOURCE msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)" @@ -327,7 +296,7 @@ msgstr "(Ðа Ñти адреÑа [разделенные запÑтой] отп #: html/Ticket/Create.html:69 msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)" -msgstr "" +msgstr "(Ðа Ñти адреÑа [разделенные запÑтой] отправлÑÑŽÑ‚ÑÑ ÐºÐ¾Ð¿Ð¸Ð¸ ÑообщениÑ. ÐдреÑа <b>ÑохранÑÑŽÑ‚ÑÑ</b> Ð´Ð»Ñ Ð¿Ð¾Ñледующих уведомлений.)" #: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33 msgid "(empty)" @@ -335,7 +304,7 @@ msgstr "(пуÑто)" #: html/Admin/Users/index.html:39 msgid "(no name listed)" -msgstr "" +msgstr "(не указано имен)" #: html/Elements/MyRequests:43 html/Elements/MyTickets:45 msgid "(no subject)" @@ -351,15 +320,11 @@ msgstr "(только один тикет)" #: html/Elements/MyRequests:52 html/Elements/MyTickets:55 msgid "(pending approval)" -msgstr "" +msgstr "(в ожидании визы)" #: html/Elements/MyRequests:54 html/Elements/MyTickets:57 msgid "(pending other tickets)" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "(requestor's group)" -msgstr "" +msgstr "(в ожидании других тикетов)" #: html/Admin/Users/Modify.html:50 msgid "(required)" @@ -367,7 +332,7 @@ msgstr "(требуетÑÑ)" #: html/Ticket/Elements/ShowTransaction:105 msgid "(untitled)" -msgstr "" +msgstr "(без названиÑ)" #: NOT FOUND IN SOURCE msgid "25 highest priority tickets I own..." @@ -390,29 +355,9 @@ msgstr "" msgid "<input type=\"submit\" value=\"New ticket in\"> %1" msgstr "<input type=\"submit\" value=\"Создать тикет в очереди\"> %1" -#: NOT FOUND IN SOURCE -msgid "??????" -msgstr "" - #: etc/initialdata:203 msgid "A blank template" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "ACE Deleted" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "ACE Loaded" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "ACE could not be deleted" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "ACE could not be found" -msgstr "" +msgstr "ПуÑтой шаблон" #: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181 msgid "ACE not found" @@ -428,7 +373,7 @@ msgstr "Прекращаем работу во избежание нежелат #: html/User/Elements/Tabs:32 msgid "About me" -msgstr "" +msgstr "Обо мне" #: html/Admin/Users/Modify.html:80 msgid "Access control" @@ -441,7 +386,7 @@ msgstr "ДейÑтвие" #: lib/RT/Scrip_Overlay.pm:147 #. ($args{'ScripAction'}) msgid "Action %1 not found" -msgstr "" +msgstr "дейÑтвие %1 не найдено" #: bin/rt-crontool:123 msgid "Action committed." @@ -461,35 +406,12 @@ msgstr "Добавить копию" #: html/Ticket/Create.html:114 html/Ticket/Update.html:100 msgid "Add More Files" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Add Next State" -msgstr "" +msgstr "Добавить еще файлы" #: html/Search/Bulk.html:88 msgid "Add Requestor" msgstr "Добавить проÑителÑ" -#: NOT FOUND IN SOURCE -msgid "Add a Scrip to this queue" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Add a Scrip which will apply to all queues" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Add a keyword selection to this queue" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Add a new a global scrip" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Add a scrip to this queue" -msgstr "" #: html/Admin/Global/Scrip.html:55 msgid "Add a scrip which will apply to all queues" @@ -507,10 +429,6 @@ msgstr "Добавить пользователей" msgid "Add new watchers" msgstr "Добавить наблюдателей" -#: NOT FOUND IN SOURCE -msgid "AddNextState" -msgstr "" - #: lib/RT/Queue_Overlay.pm:643 #. ($args{'Type'}) msgid "Added principal as a %1 for this queue" @@ -535,7 +453,7 @@ msgstr "ÐдминиÑÑ‚Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ" #: etc/initialdata:274 msgid "Admin Comment" -msgstr "" +msgstr "Комментарий админа" #: etc/initialdata:256 msgid "Admin Correspondence" @@ -561,22 +479,10 @@ msgstr "Группы" msgid "Admin/Queue/Basics" msgstr "Параметры очереди" -#: NOT FOUND IN SOURCE -msgid "AdminAllPersonalGroups" -msgstr "" - #: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89 msgid "AdminCc" msgstr "ÐдминиÑÑ‚Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ" -#: NOT FOUND IN SOURCE -msgid "AdminComment" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "AdminCorrespondence" -msgstr "" - #: lib/RT/Queue_Overlay.pm:72 msgid "AdminCustomFields" msgstr "" @@ -605,45 +511,21 @@ msgstr "" msgid "Administrative Cc" msgstr "ÐдминиÑÑ‚Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ" -#: NOT FOUND IN SOURCE -msgid "Admins" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Advanced Search" -msgstr "" - #: html/Elements/SelectDateRelation:36 msgid "After" msgstr "ПоÑле" -#: NOT FOUND IN SOURCE -msgid "Age" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Alias" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Alias for" -msgstr "" - #: html/Admin/Elements/EditCustomFields:96 msgid "All Custom Fields" -msgstr "" +msgstr "Ð’Ñе дополнительные полÑ" #: html/Admin/Queues/index.html:53 msgid "All Queues" msgstr "Ð’Ñе очереди" -#: NOT FOUND IN SOURCE -msgid "Always sends a message to the requestors independent of message sender" -msgstr "" - #: html/Elements/Tabs:58 msgid "Approval" -msgstr "" +msgstr "Виза" #: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65 #. ($Ticket->Id, $Ticket->Subject) @@ -663,14 +545,6 @@ msgstr "Виза #%1: ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð½Ðµ Ñохранены из-за Ð¾Ñ msgid "Approval #%1: Notes recorded" msgstr "Виза #%1: ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñаны" -#: NOT FOUND IN SOURCE -msgid "Approval Details" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Approval diagram" -msgstr "" - #: html/Approvals/Elements/Approve:45 msgid "Approve" msgstr "Завизировать" @@ -701,7 +575,7 @@ msgstr "Вложить файл" #: html/Ticket/Create.html:98 html/Ticket/Update.html:89 msgid "Attached file" -msgstr "" +msgstr "Вложенный файл" #: html/SelfService/Attachment/dhandler:36 msgid "Attachment '%1' could not be loaded" @@ -723,25 +597,17 @@ msgstr "ВложениÑ" msgid "Aug." msgstr "Ðвг." -#: NOT FOUND IN SOURCE -msgid "August" -msgstr "" - #: html/Admin/Elements/ModifyUser:66 msgid "AuthSystem" msgstr "Тип региÑтрации" #: etc/initialdata:206 msgid "Autoreply" -msgstr "" +msgstr "Ðвтоответ" #: etc/initialdata:72 msgid "Autoreply To Requestors" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "AutoreplyToRequestors" -msgstr "" +msgstr "Ðвтоответ инициатору запроÑа" #: NOT FOUND IN SOURCE msgid "Bad PGP Signature: %1\\n" @@ -1007,9 +873,9 @@ msgstr "Ðе могу Ñоздать пользователÑ" #: NOT FOUND IN SOURCE msgid "Could not create watcher for requestor" -msgstr "" +msgstr "Ðе могу Ñоздать Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ñ‚Ð¾Ñ€Ð° запроÑа" -#: NOT FOUND IN SOURCE +#: NOT FOUND IN SOURCÐе могу Ñоздать Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ñ‚Ð¾Ñ€Ð° запроÑаE msgid "Could not find a ticket with id %1" msgstr "Ðе могу найти тикет по идентификатору %1" @@ -1084,7 +950,7 @@ msgstr "Ðе найти Ñтого значениÑ" #: NOT FOUND IN SOURCE msgid "Couldn't find that watcher" -msgstr "" +msgstr "Ðе могу найти данного наблюдателÑ" #: NOT FOUND IN SOURCE msgid "Couldn't find user\\n" @@ -1163,11 +1029,11 @@ msgstr "Добавить поле" #: html/Admin/Queues/CustomField.html:48 #. ($QueueObj->Name()) msgid "Create a CustomField for queue %1" -msgstr "" +msgstr "Создать дополнительное поле Ð´Ð»Ñ Ð¾Ñ‡ÐµÑ€ÐµÐ´Ð¸ 1" #: html/Admin/Global/CustomField.html:48 msgid "Create a CustomField which applies to all queues" -msgstr "" +msgstr "Создать дополнительное поле Ð´Ð»Ñ Ð²Ñех очередей" #: NOT FOUND IN SOURCE msgid "Create a new Custom Field" @@ -1272,7 +1138,7 @@ msgstr "" #: lib/RT/Queue_Overlay.pm:84 msgid "CreateTicket" -msgstr "" +msgstr "Создать тикет" #: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167 msgid "Created" @@ -1305,7 +1171,7 @@ msgstr "Текущие права" #: html/Search/Listing.html:71 msgid "Current search criteria" -msgstr "" +msgstr "Текущие критерии поиÑка" #: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45 msgid "Current watchers" @@ -1314,7 +1180,7 @@ msgstr "Текущие наблюдатели" #: html/Admin/Global/CustomField.html:55 #. ($CustomField) msgid "Custom Field #%1" -msgstr "" +msgstr "Дополнительное поле #%1" #: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35 msgid "Custom Fields" @@ -1397,21 +1263,13 @@ msgstr "Даты" msgid "Dec." msgstr "Дек." -#: NOT FOUND IN SOURCE -msgid "December" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Default Autoresponse Template" -msgstr "" - #: etc/initialdata:207 msgid "Default Autoresponse template" -msgstr "" +msgstr "Шаблон автоответа по умолчанию" #: etc/initialdata:275 msgid "Default admin comment template" -msgstr "" +msgstr "Шаблон ответа админа по умолчанию" #: etc/initialdata:257 msgid "Default admin correspondence template" @@ -1423,7 +1281,7 @@ msgstr "" #: etc/initialdata:238 msgid "Default transaction template" -msgstr "" +msgstr "Шаблон транзакции по умолчанию" #: lib/RT/Transaction_Overlay.pm:645 #. ($type, $self->Field, $self->OldValue, $self->NewValue) @@ -1436,7 +1294,7 @@ msgstr "Передача прав" #: lib/RT/System.pm:63 msgid "Delegate specific rights which have been granted to you." -msgstr "" +msgstr "Делегирование отдельных прав, которые вам даны." #: lib/RT/System.pm:63 msgid "DelegateRights" @@ -1444,15 +1302,11 @@ msgstr "" #: html/User/Elements/Tabs:38 msgid "Delegation" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Delete" -msgstr "" +msgstr "Делегирование прав" #: lib/RT/Queue_Overlay.pm:90 msgid "Delete tickets" -msgstr "" +msgstr "Удаление тикетов" #: lib/RT/Queue_Overlay.pm:90 msgid "DeleteTicket" @@ -1470,14 +1324,6 @@ msgstr "Удаление Ñтого объекта нарушит ÑÑылочн msgid "Deleting this object would violate referential integrity" msgstr "Удаление Ñтого объекта нарушит ÑÑылочную целоÑтноÑÑ‚ÑŒ" -#: NOT FOUND IN SOURCE -msgid "Deleting this object would violate referential integrity." -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Deleting this object would violate referential integrity. That's bad." -msgstr "" - #: html/Approvals/Elements/Approve:46 msgid "Deny" msgstr "Отказать" @@ -1549,7 +1395,7 @@ msgstr "Ðе обновлÑÑ‚ÑŒ Ñту Ñтраницу" #: html/Search/Elements/PickRestriction:114 msgid "Don't show search results" -msgstr "" +msgstr "Ðе показывать результаты поиÑка" #: html/Ticket/Elements/ShowTransaction:105 msgid "Download" @@ -1588,7 +1434,7 @@ msgstr "Изменение ÑвÑзей" #: html/Admin/Queues/Templates.html:41 #. ($QueueObj->Name) msgid "Edit Templates for queue %1" -msgstr "" +msgstr "Редактировать шаблоны Ð´Ð»Ñ Ð¾Ñ‡ÐµÑ€ÐµÐ´Ð¸ %1" #: NOT FOUND IN SOURCE msgid "Edit keywords" @@ -1658,11 +1504,11 @@ msgstr "EmailEncoding" #: html/Admin/Elements/EditCustomField:36 msgid "Enabled (Unchecking this box disables this custom field)" -msgstr "" +msgstr "Разрешено (ÑнÑтие отметки запрещает данное дополнительное поле)" #: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53 msgid "Enabled (Unchecking this box disables this group)" -msgstr "" +msgstr "Разрешено (ÑнÑтие отметки запрещает данную группу)" #: html/Admin/Queues/Modify.html:84 msgid "Enabled (Unchecking this box disables this queue)" @@ -1670,7 +1516,7 @@ msgstr "Включена (СнÑÑ‚Ð°Ñ Ð³Ð°Ð»Ð¾Ñ‡ÐºÐ° означает Ð¾Ñ‚ÐºÐ»Ñ #: html/Admin/Elements/EditCustomFields:99 msgid "Enabled Custom Fields" -msgstr "" +msgstr "Разрешенные дополнительные полÑ" #: html/Admin/Queues/index.html:56 msgid "Enabled Queues" @@ -1683,11 +1529,11 @@ msgstr "Включен ÑÑ‚Ð°Ñ‚ÑƒÑ %1" #: lib/RT/CustomField_Overlay.pm:361 msgid "Enter multiple values" -msgstr "" +msgstr "Введите неÑколько значений" #: lib/RT/CustomField_Overlay.pm:358 msgid "Enter one value" -msgstr "" +msgstr "Введите одно значение" #: html/Ticket/Elements/EditLinks:112 msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces." @@ -1697,10 +1543,6 @@ msgstr "Введите номера или ÑÑылки на тикеты. ÐÐµÑ msgid "Error" msgstr "Ошибка" -#: NOT FOUND IN SOURCE -msgid "Error adding watcher" -msgstr "" - #: lib/RT/Queue_Overlay.pm:555 msgid "Error in parameters to Queue->AddWatcher" msgstr "Ошибка в параметрах Queue->AddWatcher" @@ -1772,7 +1614,7 @@ msgstr "" #: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34 msgid "Find group whose" -msgstr "" +msgstr "Ðайти группы, у которых" #: html/Elements/Quicksearch:25 msgid "Find new/open tickets" @@ -1784,11 +1626,7 @@ msgstr "Ðайти людей, у которых" #: html/Search/Listing.html:108 msgid "Find tickets" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Finish Approval" -msgstr "" +msgstr "ПоиÑк тикетов" #: html/Ticket/Elements/Tabs:58 msgid "First" @@ -1887,7 +1725,7 @@ msgstr "" #: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78 msgid "Group" -msgstr "" +msgstr "Групповые" #: NOT FOUND IN SOURCE msgid "Group %1 %2: %3" @@ -1901,10 +1739,6 @@ msgstr "Права группы" msgid "Group already has member" msgstr "Пользователь уже входит в группу" -#: NOT FOUND IN SOURCE -msgid "Group could not be created." -msgstr "" - #: html/Admin/Groups/Modify.html:77 #. ($create_msg) msgid "Group could not be created: %1" @@ -1998,7 +1832,7 @@ msgstr "" #: html/Admin/Elements/EditCustomFields:74 msgid "Include disabled custom fields in listing." -msgstr "" +msgstr "Включать отключенные дополнительные Ð¿Ð¾Ð»Ñ Ð² ÑпиÑок." #: html/Admin/Queues/index.html:43 msgid "Include disabled queues in listing." @@ -2357,7 +2191,7 @@ msgstr "MobilePhone" #: lib/RT/Queue_Overlay.pm:70 msgid "Modify Access Control List" -msgstr "" +msgstr "Изменить ÑпиÑок ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ Ð´Ð¾Ñтупа" #: NOT FOUND IN SOURCE msgid "Modify Custom Field %1" @@ -2365,23 +2199,15 @@ msgstr "Изменение дополнительного Ð¿Ð¾Ð»Ñ %1" #: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51 msgid "Modify Custom Fields which apply to all queues" -msgstr "" +msgstr "Изменить дополнительные полÑ, применÑемые кл вÑем очередÑм" #: lib/RT/Queue_Overlay.pm:73 msgid "Modify Scrip templates for this queue" -msgstr "" +msgstr "Изменить шаблоны Ñкриплетов Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ очереди" #: lib/RT/Queue_Overlay.pm:76 msgid "Modify Scrips for this queue" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Modify System ACLS" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Modify Template %1" -msgstr "" +msgstr "Изменить Ñкриплеты Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ очереди" #: html/Admin/Queues/CustomField.html:45 #. ($QueueObj->Name()) @@ -2401,10 +2227,6 @@ msgstr "Изменить Ñкрипт Ð´Ð»Ñ Ð¾Ñ‡ÐµÑ€ÐµÐ´Ð¸ %1" msgid "Modify a scrip which applies to all queues" msgstr "Изменение Ñкрипта, который дейÑтвует Ð´Ð»Ñ Ð²Ñех очередей" -#: NOT FOUND IN SOURCE -msgid "Modify dates for # %1" -msgstr "" - #: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29 #. ($TicketObj->Id) msgid "Modify dates for #%1" @@ -2423,29 +2245,18 @@ msgstr "Изменение глобальных прав группы" msgid "Modify global group rights." msgstr "Изменение глобальных прав группы" -#: NOT FOUND IN SOURCE -msgid "Modify global rights for groups" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Modify global rights for users" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Modify global scrips" -msgstr "" #: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60 msgid "Modify global user rights" -msgstr "" +msgstr "Изменение глобальных прав пользователÑ" #: html/Admin/Global/UserRights.html:33 msgid "Modify global user rights." -msgstr "Изменение глобальных прав пользователÑ" +msgstr "Изменение глобальных прав пользователÑ." #: lib/RT/Group_Overlay.pm:146 msgid "Modify group metadata or delete group" -msgstr "" +msgstr "Изменение метаданных группы или ее удаление" #: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35 #. ($GroupObj->Name) @@ -2493,7 +2304,7 @@ msgstr "Изменение шаблона %1" #: html/Admin/Global/Templates.html:44 msgid "Modify templates which apply to all queues" -msgstr "" +msgstr "Изменить шаблоны, которые применÑÑŽÑ‚ÑÑ ÐºÐ¾ вÑем очередÑм" #: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86 #. ($Group->Name) @@ -2502,7 +2313,7 @@ msgstr "ÐаÑтройки Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ %1" #: lib/RT/Queue_Overlay.pm:71 msgid "Modify the queue watchers" -msgstr "" +msgstr "Изменить очередь наблюдателей" #: html/Admin/Users/Modify.html:236 #. ($UserObj->Name) @@ -2521,7 +2332,7 @@ msgstr "Изменение тикета # %1" #: lib/RT/Queue_Overlay.pm:88 msgid "Modify tickets" -msgstr "" +msgstr "Изменить тикеты" #: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35 #. ($GroupObj->Name) @@ -2596,7 +2407,7 @@ msgstr "Мои визы" #: html/Approvals/index.html:25 html/Approvals/index.html:26 msgid "My approvals" -msgstr "" +msgstr "Мои визы" #: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44 msgid "Name" @@ -2606,10 +2417,6 @@ msgstr "ИмÑ" msgid "Name in use" msgstr "Ð˜Ð¼Ñ ÑƒÐ¶Ðµ иÑпользуетÑÑ" -#: NOT FOUND IN SOURCE -msgid "Need approval from system administrator" -msgstr "" - #: html/Ticket/Elements/ShowDates:52 msgid "Never" msgstr "" @@ -2632,15 +2439,15 @@ msgstr "Ðовые ÑвÑзи" #: html/Ticket/Elements/Tabs:36 msgid "New Search" -msgstr "" +msgstr "Ðовый поиÑк" #: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40 msgid "New custom field" -msgstr "" +msgstr "Ðовое дополнительное поле" #: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52 msgid "New group" -msgstr "" +msgstr "ÐÐ¾Ð²Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°" #: html/SelfService/Prefs.html:32 msgid "New password" @@ -2652,7 +2459,7 @@ msgstr "Отправлено Ñообщение Ñ Ð½Ð¾Ð²Ñ‹Ð¼ паролем" #: html/Admin/Elements/QueueTabs:70 msgid "New queue" -msgstr "" +msgstr "ÐÐ¾Ð²Ð°Ñ Ð¾Ñ‡ÐµÑ€ÐµÐ´ÑŒ" #: html/SelfService/Elements/Tabs:63 msgid "New request" @@ -2664,7 +2471,7 @@ msgstr "Ðовые права" #: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53 msgid "New scrip" -msgstr "" +msgstr "Ðовый Ñкриплет" #: NOT FOUND IN SOURCE msgid "New search" @@ -2672,7 +2479,7 @@ msgstr "Ðовый поиÑк" #: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46 msgid "New template" -msgstr "" +msgstr "Ðовый шаблон" #: lib/RT/Ticket_Overlay.pm:2771 msgid "New ticket doesn't exist" @@ -2680,7 +2487,7 @@ msgstr "Ðовый тикет не ÑущеÑтвует" #: html/Admin/Elements/UserTabs:52 msgid "New user" -msgstr "" +msgstr "Ðовый пользователь" #: html/Admin/Elements/CreateUserCalled:26 msgid "New user called" @@ -2954,7 +2761,7 @@ msgstr "Ðа" #: etc/initialdata:155 msgid "On Comment" -msgstr "" +msgstr "Ðа комментарий" #: etc/initialdata:148 msgid "On Correspond" @@ -2962,15 +2769,15 @@ msgstr "" #: etc/initialdata:137 msgid "On Create" -msgstr "" +msgstr "Ðа Ñоздание" #: etc/initialdata:169 msgid "On Owner Change" -msgstr "" +msgstr "Ðа изменение владельца" #: etc/initialdata:177 msgid "On Queue Change" -msgstr "" +msgstr "Ðа изменение очереди" #: etc/initialdata:183 msgid "On Resolve" @@ -2978,11 +2785,11 @@ msgstr "" #: etc/initialdata:161 msgid "On Status Change" -msgstr "" +msgstr "на изменение ÑтатуÑа" #: etc/initialdata:142 msgid "On Transaction" -msgstr "" +msgstr "Ðа транзакцию" #: html/Approvals/Elements/PendingMyApproval:50 #. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>") @@ -3108,7 +2915,7 @@ msgstr "Ð’ доÑтупе отказано" #: html/User/Elements/Tabs:35 msgid "Personal Groups" -msgstr "" +msgstr "Личные группы" #: html/User/Groups/index.html:30 html/User/Groups/index.html:40 msgid "Personal groups" @@ -3169,7 +2976,7 @@ msgstr "Приоритет начинаетÑÑ Ñ" #: etc/initialdata:25 msgid "Privileged" -msgstr "" +msgstr "Привилегированные" #: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163 #. (loc_fuzzy($msg)) @@ -3299,7 +3106,7 @@ msgstr "СамообÑлуживание RT / Закрытые тикеты" #: html/index.html:25 html/index.html:28 msgid "RT at a glance" -msgstr "" +msgstr "Обзор RT" #: NOT FOUND IN SOURCE msgid "RT couldn't authenticate you" @@ -3320,11 +3127,7 @@ msgstr "RT не Ñмог проверить Ñту подпиÑÑŒ PGP. \\n" #: html/Elements/PageLayout:26 #. ($RT::rtname) msgid "RT for %1" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "RT for %1: %2" -msgstr "" +msgstr "RT Ð´Ð»Ñ %1" #: NOT FOUND IN SOURCE msgid "RT has proccessed your commands" @@ -3602,39 +3405,39 @@ msgstr "" #: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50 msgid "Select group" -msgstr "" +msgstr "Выбрать группу" #: lib/RT/CustomField_Overlay.pm:355 msgid "Select multiple values" -msgstr "" +msgstr "Выбрать неÑколько значений" #: lib/RT/CustomField_Overlay.pm:352 msgid "Select one value" -msgstr "" +msgstr "Выбрать одно значение" #: html/Admin/Elements/QueueTabs:67 msgid "Select queue" -msgstr "" +msgstr "Выбрать очередь" #: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50 msgid "Select scrip" -msgstr "" +msgstr "Выбрать Ñкриплет" #: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55 msgid "Select template" -msgstr "" +msgstr "Выбрать шаблон" #: html/Admin/Elements/UserTabs:49 msgid "Select user" -msgstr "" +msgstr "Выбрать пользователÑ" #: lib/RT/CustomField_Overlay.pm:36 msgid "SelectMultiple" -msgstr "" +msgstr "Выбрать неÑколько" #: lib/RT/CustomField_Overlay.pm:35 msgid "SelectSingle" -msgstr "" +msgstr "Выбрать одно" #: html/SelfService/index.html:25 msgid "Self Service" @@ -3642,15 +3445,15 @@ msgstr "СамообÑлуживание" #: etc/initialdata:114 msgid "Send mail to all watchers" -msgstr "" +msgstr "Отправить Ñообщение вÑем наблюдателÑм" #: etc/initialdata:110 msgid "Send mail to all watchers as a \"comment\"" -msgstr "" +msgstr "Отправить Ñообщение вÑем наблюдателÑм как \"комментарий\"" #: etc/initialdata:105 msgid "Send mail to requestors and Ccs" -msgstr "" +msgstr "Отправить Ñообщение вÑем инициаторам запроÑа и CCs" #: etc/initialdata:100 msgid "Send mail to requestors and Ccs as a comment" @@ -3680,14 +3483,6 @@ msgstr "" msgid "Sep." msgstr "Сен." -#: NOT FOUND IN SOURCE -msgid "September" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Show Results" -msgstr "ИÑкать" - #: html/Approvals/Elements/PendingMyApproval:44 msgid "Show approved requests" msgstr "Показать завизированные запроÑÑ‹" @@ -3710,15 +3505,15 @@ msgstr "Показать ожидающие запроÑÑ‹" #: html/Approvals/Elements/PendingMyApproval:46 msgid "Show requests awaiting other approvals" -msgstr "" +msgstr "Показать запроÑÑ‹, ждущие других виз" #: lib/RT/Queue_Overlay.pm:81 msgid "Show ticket private commentary" -msgstr "" +msgstr "Показать приватные комментарии по тикету" #: lib/RT/Queue_Overlay.pm:79 msgid "Show ticket summaries" -msgstr "" +msgstr "Показать общую информацию по запроÑу" #: lib/RT/Queue_Overlay.pm:69 msgid "ShowACL" @@ -3822,10 +3617,6 @@ msgstr "" msgid "Status changed from %1 to %2" msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½ Ñ %1 на %2" -#: NOT FOUND IN SOURCE -msgid "StatusChange" -msgstr "" - #: html/Ticket/Elements/Tabs:147 msgid "Steal" msgstr "Отобрать" @@ -3842,16 +3633,12 @@ msgstr "Тема" #: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611 #. ($self->Data) msgid "Subject changed to %1" -msgstr "" +msgstr "Тема изменена на %1" #: html/Elements/Submit:59 msgid "Submit" msgstr "Готово" -#: NOT FOUND IN SOURCE -msgid "Submit Workflow" -msgstr "" - #: lib/RT/Group_Overlay.pm:749 msgid "Succeeded" msgstr "" @@ -3862,24 +3649,16 @@ msgstr "Ð’Ñк." #: lib/RT/System.pm:54 msgid "SuperUser" -msgstr "" +msgstr "ÐдминиÑтратор" #: html/User/Elements/DelegateRights:77 msgid "System" -msgstr "" +msgstr "СиÑтемные" #: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790 msgid "System Error" msgstr "Ошибка ÑиÑтемы" -#: NOT FOUND IN SOURCE -msgid "System Error. Right not granted." -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "System Error. right not granted" -msgstr "" - #: lib/RT/ACE_Overlay.pm:616 msgid "System error. Right not delegated." msgstr "Ошибка ÑиÑтемы. Право не было делегировано." @@ -3888,17 +3667,13 @@ msgstr "Ошибка ÑиÑтемы. Право не было делегиров msgid "System error. Right not granted." msgstr "Ошибка ÑиÑтемы. Право не было выдано." -#: NOT FOUND IN SOURCE -msgid "System error. Unable to grant rights." -msgstr "" - #: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36 msgid "System groups" msgstr "СиÑтемные группы" #: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53 msgid "SystemRolegroup for internal use" -msgstr "" +msgstr "СиÑÑ‚ÐµÐ¼Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð° Ð´Ð»Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½ÐµÐ³Ð¾ иÑпользованиÑ" #: lib/RT/CurrentUser.pm:320 msgid "TEST_STRING" @@ -3919,11 +3694,11 @@ msgstr "Шаблон" #: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90 #. ($TemplateObj->Id()) msgid "Template #%1" -msgstr "" +msgstr "Шаблон #%1" #: html/Admin/Elements/EditTemplates:89 msgid "Template deleted" -msgstr "" +msgstr "Шаблон удален" #: lib/RT/Scrip_Overlay.pm:153 msgid "Template not found" @@ -3947,7 +3722,7 @@ msgstr "Шаблоны Ð´Ð»Ñ %1\\n" #: lib/RT/Interface/Web.pm:858 msgid "That is already the current value" -msgstr "" +msgstr "Ðто уже текущее значение" #: lib/RT/CustomField_Overlay.pm:178 msgid "That is not a value for this custom field" @@ -4013,10 +3788,6 @@ msgstr "Ðтот пользователь теперь имеет вÑе полРmsgid "That user is now unprivileged" msgstr "Ðтот пользователь теперь не имеет полномочий" -#: NOT FOUND IN SOURCE -msgid "That user is now unprivilegedileged" -msgstr "" - #: lib/RT/Ticket_Overlay.pm:2944 msgid "That user may not own tickets in that queue" msgstr "Ðтот пользователь не может владеть тикетами из Ñтой очереди" @@ -4051,15 +3822,15 @@ msgstr "Ðти команды не были иÑполнены:\\n\\n" #: lib/RT/Interface/Web.pm:861 msgid "The new value has been set." -msgstr "" +msgstr "Ðовое значение уÑтановлено" #: lib/RT/ACE_Overlay.pm:86 msgid "The owner of a ticket" -msgstr "" +msgstr "Владелец тикета" #: lib/RT/ACE_Overlay.pm:87 msgid "The requestor of a ticket" -msgstr "" +msgstr "Кто отправил тикет" #: html/Admin/Elements/EditUserComments:26 msgid "These comments aren't generally visible to the user" @@ -4080,7 +3851,7 @@ msgstr "Похоже, что Ñта Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð½Ðµ имеет инфР#: html/Ticket/Elements/ShowRequestor:47 #. ($rows) msgid "This user's %1 highest priority tickets" -msgstr "" +msgstr "%1 тикетов макÑимального приоритета Ñтого пользователÑ" #: NOT FOUND IN SOURCE msgid "This user's 25 highest priority tickets" @@ -4090,18 +3861,6 @@ msgstr "25 важнейших тикетов пользователÑ..." msgid "Thu." msgstr "Чтв." -#: NOT FOUND IN SOURCE -msgid "Ticket" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Ticket # %1 %2" -msgstr "Тикет # %1 %2" - -#: NOT FOUND IN SOURCE -msgid "Ticket # %1 Jumbo update: %2" -msgstr "" - #: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29 #. ($Ticket->Id, $Ticket->Subject) msgid "Ticket #%1 Jumbo update: %2" @@ -4154,7 +3913,7 @@ msgstr "Тип данных тикета" #: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597 msgid "Ticket could not be created due to an internal error" -msgstr "" +msgstr "Тикет не может быть Ñоздан из-за внутренней ошибки" #: lib/RT/Transaction_Overlay.pm:522 msgid "Ticket created" @@ -4172,17 +3931,13 @@ msgstr "Тикет удален" msgid "Ticket id not found" msgstr "Идентификатор тикета не найден" -#: NOT FOUND IN SOURCE -msgid "Ticket killed" -msgstr "" - #: html/REST/1.0/modify:36 html/REST/1.0/update:41 msgid "Ticket not found" msgstr "Тикет не найден" #: etc/initialdata:289 msgid "Ticket status changed" -msgstr "" +msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ‚Ð¸ÐºÐµÑ‚Ð° изменен" #: html/Ticket/Update.html:39 msgid "Ticket watchers" @@ -4190,7 +3945,7 @@ msgstr "Ðаблюдатели Ð´Ð»Ñ Ñ‚Ð¸ÐºÐµÑ‚Ð°" #: html/Elements/Tabs:49 msgid "Tickets" -msgstr "" +msgstr "Тикеты" #: lib/RT/Tickets_Overlay.pm:1383 #. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'})) @@ -4231,21 +3986,17 @@ msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°" msgid "Time worked" msgstr "Ð’ работе" -#: NOT FOUND IN SOURCE -msgid "TimeLeft" -msgstr "" - #: lib/RT/Ticket_Overlay.pm:1165 msgid "TimeWorked" -msgstr "" +msgstr "Ð’ работе" #: bin/rt-commit-handler:402 msgid "To generate a diff of this commit:" -msgstr "Ð”Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ дифа Ñтого коммита:" +msgstr "Ð”Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ изменений Ñтого коммита:" #: bin/rt-commit-handler:391 msgid "To generate a diff of this commit:\\n" -msgstr "Ð”Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ дифа Ñтого коммита:\\n" +msgstr "Ð”Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ изменений Ñтого коммита:\\n" #: lib/RT/Ticket_Overlay.pm:1168 msgid "Told" @@ -4253,7 +4004,7 @@ msgstr "Контакт" #: etc/initialdata:237 msgid "Transaction" -msgstr "" +msgstr "ТранзакциÑ" #: lib/RT/Transaction_Overlay.pm:642 #. ($self->Data) @@ -4307,7 +4058,7 @@ msgstr "Ðе ограничено" #: etc/initialdata:32 msgid "Unprivileged" -msgstr "" +msgstr "Ðепривилегированный" #: lib/RT/Transaction_Overlay.pm:571 msgid "Untaken" @@ -4361,12 +4112,12 @@ msgstr "Обновить тикет # %1" #: html/SelfService/Update.html:50 #. ($Ticket->id) msgid "Update ticket #%1" -msgstr "Обновить тикет # %1" +msgstr "Обновить тикет #%1" #: html/Ticket/Update.html:135 #. ($Ticket->id, $Ticket->Subject) msgid "Update ticket #%1 (%2)" -msgstr "" +msgstr "Обновить тикет #%1 (%2)" #: lib/RT/Interface/Web.pm:373 msgid "Update type was neither correspondence nor comment." @@ -4461,10 +4212,6 @@ msgstr "" msgid "WatchAsAdminCc" msgstr "" -#: NOT FOUND IN SOURCE -msgid "Watcher loaded" -msgstr "" - #: html/Admin/Elements/QueueTabs:42 msgid "Watchers" msgstr "Ðаблюдатели" @@ -4585,19 +4332,15 @@ msgstr "ÐдминиÑтратор RT неправильно наÑтроил п #: etc/initialdata:429 etc/upgrade/2.1.71:146 msgid "Your request has been approved by %1. Other approvals may still be pending." -msgstr "" +msgstr "Ваш Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ð» %1. Другие Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ продолжать находитьÑÑ Ð² ожидании." #: etc/initialdata:463 etc/upgrade/2.1.71:180 msgid "Your request has been approved." -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "Your request was rejected" -msgstr "" +msgstr "Ваш Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½." #: etc/initialdata:384 etc/upgrade/2.1.71:101 msgid "Your request was rejected." -msgstr "" +msgstr "Ваш Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð±Ñ‹Ð» отвергнут." #: html/autohandler:136 html/autohandler:142 msgid "Your username or password is incorrect" @@ -4607,10 +4350,6 @@ msgstr "Ð’Ñ‹ ввели неверное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ пароль" msgid "Zip" msgstr "ИндекÑ" -#: NOT FOUND IN SOURCE -msgid "[no subject]" -msgstr "" - #: html/User/Elements/DelegateRights:59 #. ($right->PrincipalObj->Object->SelfDescription) msgid "as granted to %1" @@ -4640,10 +4379,6 @@ msgstr "отправлено Ñообщение" msgid "days" msgstr "дней" -#: NOT FOUND IN SOURCE -msgid "dead" -msgstr "" - #: html/Search/Listing.html:75 msgid "delete" msgstr "удалить" @@ -4664,10 +4399,6 @@ msgstr "не Ñодержит" msgid "equal to" msgstr "равнÑетÑÑ" -#: NOT FOUND IN SOURCE -msgid "false" -msgstr "" - #: html/Elements/SelectAttachmentField:28 msgid "filename" msgstr "Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°" @@ -4737,10 +4468,6 @@ msgstr "нет" msgid "not equal to" msgstr "не равен" -#: NOT FOUND IN SOURCE -msgid "notlike" -msgstr "" - #: lib/RT/Queue_Overlay.pm:59 msgid "open" msgstr "открыт" @@ -4790,17 +4517,9 @@ msgstr "вызывающий компонент не указал причину msgid "ticket #%1 %2" msgstr "тикет #%1 %2" -#: NOT FOUND IN SOURCE -msgid "true" -msgstr "" - #: lib/RT/Group_Overlay.pm:216 #. ($self->Id) msgid "undescribed group %1" -msgstr "" - -#: NOT FOUND IN SOURCE -msgid "undescripbed group %1" msgstr "неопиÑÐ°Ð½Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð° %1" #: lib/RT/Group_Overlay.pm:191 @@ -4819,8 +4538,3 @@ msgstr "Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð¾Ð¼ %1" #: lib/RT/Date.pm:331 msgid "years" msgstr "лет" - -#: NOT FOUND IN SOURCE -msgid "ニックãƒãƒ¼ãƒ " -msgstr "" - diff --git a/rt/lib/RT/I18N/zh_cn.po b/rt/lib/RT/I18N/zh_cn.po index ededc1ac3..0f0b8da60 100644 --- a/rt/lib/RT/I18N/zh_cn.po +++ b/rt/lib/RT/I18N/zh_cn.po @@ -1,4 +1,4 @@ -# Traditional Chinese localization catalog for Request Tracker (RT) +# Chinese localization catalog for Request Tracker (RT) msgid "" msgstr "" "Last-Translator: Autrijus Tang <autrijus@autrijus.org>\n" @@ -7,7 +7,7 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: html/Elements/MyRequests:27 html/Elements/MyTickets:27 html/Work/Elements/MyApprovals:8 html/Work/Elements/MyRequests:9 html/Work/Elements/MyTickets:9 +#: html/Elements/MyRequests:27 html/Elements/MyTickets:27 html/Work/Elements/MyApprovals:8 html/Work/Elements/MyRequests:15 html/Work/Elements/MyTickets:15 msgid "#" msgstr "#" @@ -40,7 +40,7 @@ msgstr "%*(%1) 件尚未解决的申请å•" msgid "%1 %2" msgstr "%1 %2" -#: lib/RT/Tickets_Overlay.pm:771 +#: lib/RT/Tickets_Overlay.pm:790 #. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'}) msgid "%1 %2 %3" msgstr "%1 %2 %3" @@ -50,10 +50,11 @@ msgstr "%1 %2 %3" msgid "%1 %2 %3 %4:%5:%6 %7" msgstr "%7-%2-%3 %4:%5:%6 %1" -#: lib/RT/Ticket_Overlay.pm:3541 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Overlay.pm:599 +#: lib/RT/Ticket_Overlay.pm:3588 lib/RT/Transaction_Overlay.pm:514 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Vendor.pm:19 #. ($cf->Name, $new_value->Content) #. ($field, $self->NewValue) #. ($self->Field, $principal->Object->Name) +#. ($field, $new_value) msgid "%1 %2 added" msgstr "%2 已新增为 %1" @@ -62,16 +63,18 @@ msgstr "%2 已新增为 %1" msgid "%1 %2 ago" msgstr "%1 %2 之å‰" -#: lib/RT/Ticket_Overlay.pm:3547 lib/RT/Transaction_Overlay.pm:564 +#: lib/RT/Ticket_Overlay.pm:3594 lib/RT/Transaction_Overlay.pm:521 lib/RT/Transaction_Vendor.pm:25 #. ($cf->Name, $old_value, $new_value->Content) #. ($field, $self->OldValue, $self->NewValue) +#. ($field, $old_value, $new_value) msgid "%1 %2 changed to %3" msgstr "%1 已从 %2 改为 %3" -#: lib/RT/Ticket_Overlay.pm:3544 lib/RT/Transaction_Overlay.pm:560 lib/RT/Transaction_Overlay.pm:605 +#: lib/RT/Ticket_Overlay.pm:3591 lib/RT/Transaction_Overlay.pm:517 lib/RT/Transaction_Overlay.pm:563 lib/RT/Transaction_Vendor.pm:22 #. ($cf->Name, $old_value) #. ($field, $self->OldValue) #. ($self->Field, $principal->Object->Name) +#. ($field, $old_value) msgid "%1 %2 deleted" msgstr "%2 已自 %1 åˆ é™¤" @@ -121,17 +124,17 @@ msgstr "%1 - 指定欲使用的æ¡ä»¶æ¨¡å—" msgid "%1 - Specify the search module you want to use" msgstr "%1 - 指定欲使用的查询模å—" -#: lib/RT/ScripAction_Overlay.pm:121 +#: lib/RT/ScripAction_Overlay.pm:122 #. ($self->Id) msgid "%1 ScripAction loaded" msgstr "åŠ è½½æ‰‹ç» %1" -#: html/Edit/Elements/Page:48 +#: html/Edit/Elements/Page:49 #. (scalar $count) msgid "%1 Total" msgstr "å…± %1 笔" -#: lib/RT/Ticket_Overlay.pm:3574 +#: lib/RT/Ticket_Overlay.pm:3621 #. ($args{'Value'}, $cf->Name) msgid "%1 added as a value for %2" msgstr "新增 %1 作为 %2 的值" @@ -154,13 +157,13 @@ msgstr "别å %1 需è¦å¯ç”¨çš„申请å•ç¼–å·ä»¥å¤„ç† %3(出自 %2)" msgid "%1 appears to be a local object, but can't be found in the database" msgstr "%1 看æ¥æ˜¯ä¸ªæœ¬åœ°å¯¹è±¡ï¼Œå´ä¸åœ¨æ•°æ®åº“里" -#: html/Ticket/Elements/ShowDates:51 lib/RT/Transaction_Overlay.pm:481 +#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:430 #. ($self->BriefDescription , $self->CreatorObj->Name) #. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name) msgid "%1 by %2" msgstr "%1 (%2)" -#: lib/RT/Transaction_Overlay.pm:535 lib/RT/Transaction_Overlay.pm:624 lib/RT/Transaction_Overlay.pm:633 lib/RT/Transaction_Overlay.pm:636 +#: lib/RT/Transaction_Overlay.pm:484 lib/RT/Transaction_Overlay.pm:649 lib/RT/Transaction_Overlay.pm:658 lib/RT/Transaction_Overlay.pm:661 #. ($self->Field , ( $self->OldValue || $no_value ) , $self->NewValue) #. ($self->Field , $q1->Name , $q2->Name) #. ($self->Field, $t2->AsString, $t1->AsString) @@ -168,7 +171,7 @@ msgstr "%1 (%2)" msgid "%1 changed from %2 to %3" msgstr "%1 的值从 %2 改为 %3" -#: lib/RT/Interface/Web.pm:893 +#: lib/RT/Interface/Web.pm:953 msgid "%1 could not be set to %2." msgstr "æ— æ³•å°† %1 设定为 %2。" @@ -176,17 +179,17 @@ msgstr "æ— æ³•å°† %1 设定为 %2。" msgid "%1 couldn't init a transaction (%2)\\n" msgstr "%1 æ— æ³•åˆå§‹æ›´æ–° (%2)\\n" -#: lib/RT/Ticket_Overlay.pm:2839 +#: lib/RT/Ticket_Overlay.pm:2880 #. ($self) msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent." msgstr "%1 æ— æ³•å°†çŽ°å†µè®¾æˆå·²è§£å†³ã€‚RT æ•°æ®åº“内容å¯èƒ½ä¸ä¸€è‡´ã€‚" -#: html/Elements/MyTickets:24 html/Work/Elements/MyTickets:6 +#: html/Elements/MyTickets:24 html/Work/Elements/MyTickets:9 #. ($rows) msgid "%1 highest priority tickets I own..." msgstr "å‰ %1 份待处ç†ç”³è¯·å•..." -#: html/Elements/MyRequests:24 html/Work/Elements/MyRequests:6 +#: html/Elements/MyRequests:24 html/Work/Elements/MyRequests:9 #. ($rows) msgid "%1 highest priority tickets I requested..." msgstr "å‰ %1 份é€å‡ºçš„申请å•..." @@ -206,12 +209,12 @@ msgstr "%1 是从外部排程程åº(如 cron)æ¥å¯¹ç”³è¯·å•è¿›è¡Œæ“ä½œçš„å·¥å… msgid "%1 is no longer a %2 for this queue." msgstr "%1 å·²ä¸å†æ˜¯æ¤è¡¨å•çš„ %2。" -#: lib/RT/Ticket_Overlay.pm:1578 +#: lib/RT/Ticket_Overlay.pm:1596 #. ($principal->Object->Name, $args{'Type'}) msgid "%1 is no longer a %2 for this ticket." msgstr "%1 å·²ä¸å†æ˜¯æ¤ç”³è¯·å•çš„ %2。" -#: lib/RT/Ticket_Overlay.pm:3630 +#: lib/RT/Ticket_Overlay.pm:3677 #. ($args{'Value'}, $cf->Name) msgid "%1 is no longer a value for custom field %2" msgstr "%1 å·²ä¸å†æ˜¯è‡ªè®¢å—段 %2 的值。" @@ -264,17 +267,17 @@ msgstr "%1 会解决在已解决群组里æˆå‘˜çš„申请å•ã€‚" msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request." msgstr "如果 %1 起始申请å•ä¾èµ–于æŸä¸ªé“¾æŽ¥ï¼Œæˆ–是æŸä¸ªé“¾æŽ¥çš„æˆå‘˜ï¼Œå®ƒå°†ä¼šè¢«å»¶å®•ã€‚" -#: lib/RT/Transaction_Overlay.pm:433 +#: lib/RT/Transaction_Overlay.pm:382 lib/RT/Transaction_Vendor.pm:37 #. ($self) msgid "%1: no attachment specified" msgstr "%1:未指定附件" -#: html/Ticket/Elements/ShowTransaction:89 html/Work/Tickets/Elements/ShowTransaction:152 +#: html/Ticket/Elements/ShowTransaction:100 html/Work/Tickets/Elements/ShowTransaction:158 #. ($size) msgid "%1b" msgstr "%1 å—节" -#: html/Ticket/Elements/ShowTransaction:86 html/Work/Tickets/Elements/ShowTransaction:149 +#: html/Ticket/Elements/ShowTransaction:97 html/Work/Tickets/Elements/ShowTransaction:155 #. (int($size/102.4)/10) msgid "%1k" msgstr "%1k å—节" @@ -283,7 +286,7 @@ msgstr "%1k å—节" msgid "%quant(%1,result) found" msgstr "找到 %1 项结果" -#: lib/RT/Ticket_Overlay.pm:1148 +#: lib/RT/Ticket_Overlay.pm:1185 #. ($args{'Status'}) msgid "'%1' is an invalid value for status" msgstr "'%1' ä¸æ˜¯ä¸€ä¸ªåˆæ³•çš„状æ€å€¼" @@ -300,7 +303,7 @@ msgstr "(ç‚¹é€‰æ¬²åˆ é™¤çš„æˆå‘˜)" msgid "(Check box to delete scrip)" msgstr "(ç‚¹é€‰æ¬²åˆ é™¤çš„æ‰‹ç»)" -#: html/Admin/Elements/EditCustomFieldValues:24 html/Admin/Elements/EditQueueWatchers:28 html/Admin/Elements/EditScrips:34 html/Admin/Elements/EditTemplates:35 html/Admin/Elements/EditWorkflows:36 html/Admin/Groups/Members.html:51 html/Ticket/Elements/EditLinks:32 html/Ticket/Elements/EditPeople:45 html/User/Groups/Members.html:54 +#: html/Admin/Elements/EditCustomFieldValues:24 html/Admin/Elements/EditQueueWatchers:28 html/Admin/Elements/EditScrips:34 html/Admin/Elements/EditTemplates:35 html/Admin/Elements/EditWorkflows:36 html/Admin/Groups/Members.html:51 html/Ticket/Elements/EditLinks:32 html/Ticket/Elements/EditPeople:45 html/User/Groups/Members.html:54 html/Work/Tickets/Elements/EditLinks:20 html/Work/Tickets/Elements/EditPeople:36 msgid "(Check box to delete)" msgstr "(ç‚¹é€‰æ¬²åˆ é™¤çš„é¡¹ç›®)" @@ -308,7 +311,7 @@ msgstr "(ç‚¹é€‰æ¬²åˆ é™¤çš„é¡¹ç›®)" msgid "(Check boxes to delete)" msgstr "(ç‚¹é€‰æ¬²åˆ é™¤çš„é¡¹ç›®)" -#: html/Ticket/Create.html:177 +#: html/Ticket/Create.html:178 msgid "(Enter ticket ids or URLs, seperated with spaces)" msgstr "(键入申请å•ç¼–å·æˆ–网å€ï¼Œä»¥ç©ºç™½åˆ†éš”)" @@ -342,7 +345,7 @@ msgstr "没有模æ¿" msgid "(No workflows)" msgstr "没有æµç¨‹" -#: html/Ticket/Update.html:83 html/Work/Tickets/Update.html:52 +#: html/Ticket/Update.html:83 html/Work/Tickets/Update.html:56 msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)" msgstr "(é€å‡ºæœ¬ä»½æ›´æ–°çš„密件副本给åå•ä¸Šä»¥é€—å·éš”开的电å邮件地å€ã€‚è¿™<b>ä¸ä¼š</b>更改åŽç»çš„收件者åå•ã€‚)" @@ -366,7 +369,7 @@ msgstr "(é€å‡ºæœ¬ä»½æ›´æ–°çš„副本给åå•ä¸Šä»¥é€—å·éš”开的电åé‚®ä»¶åœ msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)" msgstr "(é€å‡ºæœ¬ä»½æ›´æ–°çš„副本给åå•ä¸Šä»¥é€—å·éš”开的电å邮件地å€ã€‚è¿™<b>将会</b>更改åŽç»çš„收件者åå•ã€‚)" -#: html/Ticket/Elements/EditCustomFieldEntries:35 html/Work/Tickets/Elements/EditCustomFieldEntries:33 html/Work/Tickets/Elements/ShowCustomFieldEntries:13 +#: html/Ticket/Elements/EditCustomFieldEntries:35 html/Work/Tickets/Elements/EditCustomFieldEntries:43 html/Work/Tickets/Elements/ShowCustomFieldEntries:14 msgid "(delete)" msgstr "(åˆ é™¤)" @@ -374,7 +377,7 @@ msgstr "(åˆ é™¤)" msgid "(empty)" msgstr "(空白)" -#: html/Edit/Global/CustomField/index.html:113 html/Edit/Global/Scrip/index.html:111 html/Edit/Global/Template/index.html:106 +#: html/Edit/Elements/Index:87 html/Edit/Global/CustomField/index.html:116 html/Edit/Global/Scrip/index.html:111 html/Edit/Global/Template/index.html:106 msgid "(new)" msgstr "(新增)" @@ -382,23 +385,23 @@ msgstr "(新增)" msgid "(no name listed)" msgstr "(没有列出姓å)" -#: html/Elements/MyRequests:42 html/Elements/MyTickets:44 html/Work/Elements/MyApprovals:37 html/Work/Elements/MyRequests:36 html/Work/Elements/MyTickets:41 +#: html/Elements/MyRequests:42 html/Elements/MyTickets:44 html/Work/Elements/MyApprovals:37 html/Work/Elements/MyRequests:43 html/Work/Elements/MyTickets:52 msgid "(no subject)" msgstr "(没有主题)" -#: html/Admin/Elements/SelectRights:47 html/Elements/SelectCustomFieldValue:29 html/Ticket/Elements/EditCustomField:60 html/Ticket/Elements/EditCustomFieldValues:52 html/Ticket/Elements/ShowCustomFields:35 html/Work/Elements/EditCustomFieldValues:50 html/Work/Elements/EditCustomFields:32 html/Work/Tickets/Elements/EditCustomFieldValues:33 lib/RT/Transaction_Overlay.pm:534 +#: html/Admin/Elements/SelectRights:47 html/Elements/SelectCustomFieldValue:29 html/Ticket/Elements/EditCustomField:64 html/Ticket/Elements/EditCustomFieldValues:52 html/Ticket/Elements/ShowCustomFields:35 html/Work/Elements/EditCustomFieldValues:50 html/Work/Elements/EditCustomFields:32 html/Work/Tickets/Elements/EditCustomFieldValues:33 lib/RT/Transaction_Overlay.pm:483 msgid "(no value)" msgstr "(æ— )" -#: html/Ticket/Elements/BulkLinks:27 html/Ticket/Elements/EditLinks:115 html/Work/Search/BulkLinks:3 +#: html/Ticket/Elements/BulkLinks:27 html/Ticket/Elements/EditLinks:98 html/Work/Search/BulkLinks:3 html/Work/Tickets/Elements/EditLinks:102 msgid "(only one ticket)" msgstr "(仅能指定一份申请å•)" -#: html/Elements/MyRequests:51 html/Elements/MyTickets:54 html/Work/Elements/List:17 html/Work/Elements/MyRequests:46 html/Work/Elements/MyTickets:56 html/Work/Tickets/Elements/ShowBasics:44 +#: html/Elements/MyRequests:51 html/Elements/MyTickets:54 html/Work/Elements/List:17 html/Work/Elements/MyRequests:53 html/Work/Elements/MyTickets:67 html/Work/Tickets/Elements/ShowBasics:52 msgid "(pending approval)" msgstr "(ç‰å¾…ç¾æ ¸)" -#: html/Elements/MyRequests:53 html/Elements/MyTickets:56 html/Work/Elements/MyRequests:48 html/Work/Elements/MyTickets:58 +#: html/Elements/MyRequests:53 html/Elements/MyTickets:56 html/Work/Elements/MyRequests:55 html/Work/Elements/MyTickets:69 msgid "(pending other tickets)" msgstr "(ç‰å¾…其它申请å•)" @@ -406,23 +409,15 @@ msgstr "(ç‰å¾…其它申请å•)" msgid "(requestor's group)" msgstr "(申请人所属)" -#: html/Admin/Users/Modify.html:49 +#: html/Admin/Users/Modify.html:49 html/Edit/Users/Info:26 msgid "(required)" msgstr "(å¿…å¡«)" -#: html/Ticket/Elements/ShowTransaction:92 html/Work/Tickets/Elements/ShowTransaction:37 +#: html/Ticket/Elements/ShowTransaction:103 html/Work/Tickets/Elements/ShowTransaction:44 msgid "(untitled)" msgstr "(未命å)" #: NOT FOUND IN SOURCE -msgid "25 highest priority tickets I own..." -msgstr "å‰ 25 份待处ç†ç”³è¯·å•..." - -#: NOT FOUND IN SOURCE -msgid "25 highest priority tickets I requested..." -msgstr "å‰ 25 份é€å‡ºçš„申请å•..." - -#: NOT FOUND IN SOURCE msgid ":" msgstr ":" @@ -434,12 +429,12 @@ msgstr "<% $Ticket->Status%>" msgid "<% $_ %>" msgstr "<% $_ %>" -#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:25 html/Work/Elements/104Header:43 +#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:25 html/Work/Elements/104Header:43 lib/RT/StyleGuide.pod:767 #. ($m->scomp('/Elements/SelectNewTicketQueue')) msgid "<input type=\"submit\" value=\"New ticket in\"> %1" msgstr "<input type=\"submit\" value=\"æ出申请å•\"> %1" -#: etc/initialdata:221 +#: etc/initialdata:203 msgid "A blank template" msgstr "空白模æ¿" @@ -459,7 +454,7 @@ msgstr "æ— æ³•åˆ é™¤ ACE" msgid "ACE could not be found" msgstr "找ä¸åˆ° ACE" -#: lib/RT/ACE_Overlay.pm:156 lib/RT/Principal_Overlay.pm:179 +#: lib/RT/ACE_Overlay.pm:156 lib/RT/Principal_Overlay.pm:180 msgid "ACE not found" msgstr "找ä¸åˆ° ACE 设定" @@ -487,11 +482,11 @@ msgstr "系统使用登录æƒé™" msgid "Access control" msgstr "å˜å–æƒé™" -#: html/Admin/Elements/EditScrip:56 html/Work/Tickets/Elements/ShowTransaction:18 +#: html/Admin/Elements/EditScrip:56 html/Work/Tickets/Elements/ShowTransaction:21 msgid "Action" msgstr "动作" -#: lib/RT/Scrip_Overlay.pm:146 +#: lib/RT/Scrip_Overlay.pm:148 #. ($args{'ScripAction'}) msgid "Action %1 not found" msgstr "动作 %1 找ä¸åˆ°" @@ -504,11 +499,11 @@ msgstr "动作执行完毕" msgid "Action prepared..." msgstr "动作准备完毕..." -#: html/Work/Elements/List:13 html/Work/Elements/SelectSearch:24 html/Work/Tickets/Create.html:26 html/Work/Tickets/Elements/ShowBasics:12 +#: html/Work/Elements/List:13 html/Work/Elements/SelectSearch:25 html/Work/Tickets/Create.html:27 html/Work/Tickets/Elements/ShowBasics:12 msgid "Activated Date" msgstr "申请激活时间" -#: html/Edit/Elements/104Buttons:71 html/Edit/Elements/ListButtons:7 +#: html/Edit/Elements/104Buttons:82 html/Edit/Elements/ListButtons:7 msgid "Add" msgstr "新增" @@ -520,11 +515,11 @@ msgstr "新增管ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" msgid "Add Cc" msgstr "新增副本收件人" -#: html/Ticket/Elements/EditCustomFieldEntries:71 html/Work/Tickets/Elements/ShowCustomFieldEntries:49 +#: html/Ticket/Elements/EditCustomFieldEntries:71 html/Work/Tickets/Elements/ShowCustomFieldEntries:50 msgid "Add Entry" msgstr "新增列" -#: html/Ticket/Create.html:113 html/Ticket/Update.html:98 html/Work/Tickets/Elements/AddAttachments:18 +#: html/Ticket/Create.html:113 html/Ticket/Update.html:98 html/Work/Tickets/Elements/AddAttachments:23 msgid "Add More Files" msgstr "新增更多附件" @@ -585,16 +580,20 @@ msgstr "新增下一项关å¡" msgid "Added principal as a %1 for this queue" msgstr "å•ä½å·²æ–°å¢žä¸ºæ¤è¡¨å•çš„ %1" -#: lib/RT/Ticket_Overlay.pm:1462 +#: lib/RT/Ticket_Overlay.pm:1480 #. ($self->loc($args{'Type'})) msgid "Added principal as a %1 for this ticket" msgstr "å•ä½å·²æ–°å¢žä¸ºæ¤ç”³è¯·å•çš„ %1" -#: html/Admin/Elements/ModifyUser:75 html/Admin/Users/Modify.html:121 html/User/Prefs.html:87 html/Work/Preferences/Info:76 +#: html/Edit/Global/CustomField/Top:52 +msgid "Additional Hints" +msgstr "é¢å¤–æ示" + +#: html/Admin/Elements/ModifyUser:75 html/Admin/Users/Modify.html:121 html/User/Prefs.html:114 html/Work/Preferences/Info:79 msgid "Address1" msgstr "ä½å€" -#: html/Admin/Elements/ModifyUser:77 html/Admin/Users/Modify.html:126 html/User/Prefs.html:89 html/Work/Preferences/Info:78 +#: html/Admin/Elements/ModifyUser:77 html/Admin/Users/Modify.html:126 html/User/Prefs.html:118 html/Work/Preferences/Info:81 msgid "Address2" msgstr "ä½å€(ç»)" @@ -602,7 +601,7 @@ msgstr "ä½å€(ç»)" msgid "Adjust Blinking Rate" msgstr "调整闪çƒé€Ÿåº¦å¿«æ…¢" -#: html/Edit/Groups/Admin:9 +#: html/Edit/Queues/List:12 msgid "Admin" msgstr "管ç†å‘˜" @@ -610,11 +609,11 @@ msgstr "管ç†å‘˜" msgid "Admin Cc" msgstr "管ç†å‘˜å‰¯æœ¬" -#: etc/initialdata:303 +#: etc/initialdata:280 msgid "Admin Comment" msgstr "管ç†å‘˜è¯„论" -#: etc/initialdata:261 +#: etc/initialdata:259 msgid "Admin Correspondence" msgstr "管ç†å‘˜å›žå¤" @@ -642,7 +641,7 @@ msgstr "管ç†/群组" msgid "Admin/Queue/Basics" msgstr "管ç†/表å•/基本信æ¯" -#: html/Edit/Global/Basic/Top:60 +#: html/Edit/Global/Basic/Top:65 msgid "AdminAddress" msgstr "管ç†å‘˜ Email" @@ -650,7 +649,7 @@ msgstr "管ç†å‘˜ Email" msgid "AdminAllPersonalGroups" msgstr "管ç†æ‰€æœ‰ä»£ç†äººç¾¤ç»„" -#: etc/initialdata:74 html/Admin/Elements/ModifyTemplateAsWorkflow:155 html/Ticket/Elements/ShowPeople:38 html/Ticket/Update.html:49 lib/RT/ACE_Overlay.pm:88 +#: etc/initialdata:56 html/Admin/Elements/ModifyTemplateAsWorkflow:155 html/Ticket/Elements/ShowPeople:38 html/Ticket/Update.html:49 html/Work/Tickets/Elements/ShowLinks:11 lib/RT/ACE_Overlay.pm:88 msgid "AdminCc" msgstr "管ç†å‘˜å‰¯æœ¬" @@ -666,7 +665,7 @@ msgstr "管ç†å‘˜å›žå¤" msgid "AdminCustomFields" msgstr "管ç†è‡ªè®¢å—段" -#: html/Edit/Groups/Admin:12 lib/RT/Group_Overlay.pm:145 +#: lib/RT/Group_Overlay.pm:145 msgid "AdminGroup" msgstr "管ç†ç¾¤ç»„" @@ -706,7 +705,7 @@ msgstr "管ç†ä½¿ç”¨è€…" msgid "Administrative" msgstr "行政类" -#: html/Admin/Queues/People.html:47 html/Ticket/Elements/EditPeople:53 +#: html/Admin/Queues/People.html:47 html/Ticket/Elements/EditPeople:53 html/Work/Tickets/Elements/EditPeople:44 msgid "Administrative Cc" msgstr "管ç†å‘˜å‰¯æœ¬" @@ -726,7 +725,7 @@ msgstr "晚于" msgid "Age" msgstr "ç»åŽ†æ—¶é—´" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:172 html/Edit/Global/Workflow/Action:39 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:172 html/Edit/Global/Workflow/Action:35 msgid "Alias" msgstr "执行其它æµç¨‹" @@ -734,11 +733,11 @@ msgstr "执行其它æµç¨‹" msgid "Alias for" msgstr "相当于" -#: html/Edit/Queues/index.html:33 html/Work/Delegates/index.html:13 html/Work/Elements/SelectSearch:11 html/Work/Queues/Select.html:14 html/Work/Queues/index.html:13 +#: html/Work/Delegates/index.html:13 html/Work/Elements/SelectSearch:11 html/Work/Queues/Select.html:14 html/Work/Queues/index.html:13 msgid "All" msgstr "全部" -#: etc/initialdata:372 +#: etc/initialdata:348 msgid "All Approvals Passed" msgstr "完æˆå…¨éƒ¨ç¾æ ¸" @@ -746,7 +745,7 @@ msgstr "完æˆå…¨éƒ¨ç¾æ ¸" msgid "All Condition" msgstr "所有æ¡ä»¶" -#: html/Admin/Elements/EditCustomFields:95 +#: html/Admin/Elements/EditCustomFields:94 msgid "All Custom Fields" msgstr "所有自订å—段" @@ -759,6 +758,10 @@ msgid "All Users" msgstr "全体员工" #: NOT FOUND IN SOURCE +msgid "All done! Now you can proceed to %1." +msgstr "处ç†å®Œæ¯•ï¼æ‚¨çŽ°åœ¨å¯ä»¥ç»§ç»è¿›è¡Œ %1。" + +#: NOT FOUND IN SOURCE msgid "Allowance Request" msgstr "ç¦åˆ©è¡¥åŠ©ç”³è¯·" @@ -774,7 +777,7 @@ msgstr "æ•°é¢" msgid "Any Condition" msgstr "ä»»æ„æ¡ä»¶" -#: html/Edit/Global/Scrip/List:10 html/Edit/Global/Scrip/Top:74 +#: html/Edit/Global/Scrip/List:10 html/Edit/Global/Scrip/Top:86 msgid "Apply Template" msgstr "引用模æ¿" @@ -811,11 +814,11 @@ msgstr "ç¾æ ¸æ—¶é™" msgid "Approval Notes" msgstr "ç¾æ ¸æ„è§" -#: etc/initialdata:357 +#: etc/initialdata:336 msgid "Approval Passed" msgstr "完æˆæŸé¡¹ç¾æ ¸" -#: etc/initialdata:383 +#: etc/initialdata:359 msgid "Approval Rejected" msgstr "驳回æŸé¡¹ç¾æ ¸" @@ -843,11 +846,11 @@ msgstr "æ ¸å‡†" msgid "Approver" msgstr "ç¾æ ¸äºº" -#: html/Edit/Global/Workflow/Action:29 html/Edit/Global/Workflow/Owner.html:10 +#: html/Edit/Global/Workflow/Action:25 html/Edit/Global/Workflow/Owner.html:10 msgid "Approver Setting" msgstr "执行ç¾æ ¸äººè®¾å®š" -#: etc/initialdata:516 etc/upgrade/2.1.71:148 html/Edit/Elements/CreateApprovalsQueue:122 +#: etc/initialdata:486 etc/upgrade/2.1.71:148 html/Edit/Elements/CreateApprovalsQueue:122 msgid "Approver's notes: %1" msgstr "ç¾æ ¸å¤‡æ³¨ï¼š%1" @@ -871,15 +874,15 @@ msgstr "您确定è¦åˆ 除?" msgid "Ascending" msgstr "递增" -#: html/Search/Bulk.html:136 html/SelfService/Update.html:32 html/Ticket/ModifyAll.html:82 html/Ticket/Update.html:98 html/Work/Search/Bulk.html:88 +#: html/Search/Bulk.html:136 html/SelfService/Update.html:47 html/Ticket/ModifyAll.html:82 html/Ticket/Update.html:98 html/Work/Search/Bulk.html:88 msgid "Attach" msgstr "附件" -#: html/SelfService/Create.html:64 html/Ticket/Create.html:109 html/Work/Tickets/Elements/AddAttachments:15 +#: html/SelfService/Create.html:64 html/Ticket/Create.html:109 html/Work/Tickets/Elements/AddAttachments:19 msgid "Attach file" msgstr "é™„åŠ æ¡£æ¡ˆ" -#: html/Ticket/Create.html:97 html/Ticket/Update.html:87 html/Work/Tickets/Elements/AddAttachments:6 +#: html/SelfService/Update.html:36 html/Ticket/Create.html:97 html/Ticket/Update.html:87 html/Work/Tickets/Elements/AddAttachments:7 html/Work/Tickets/Elements/ShowAttachments:9 msgid "Attached file" msgstr "现有附件" @@ -887,15 +890,15 @@ msgstr "现有附件" msgid "Attachment '%1' could not be loaded" msgstr "æ— æ³•åŠ è½½é™„ä»¶ '%1'" -#: lib/RT/Transaction_Overlay.pm:441 +#: lib/RT/Transaction_Overlay.pm:390 lib/RT/Transaction_Vendor.pm:50 msgid "Attachment created" msgstr "附件新增完毕" -#: lib/RT/Tickets_Overlay.pm:1189 +#: lib/RT/Tickets_Overlay.pm:1208 msgid "Attachment filename" msgstr "附件档å" -#: html/Ticket/Elements/ShowAttachments:25 html/Work/Tickets/Elements/ShowTransaction:32 +#: html/Ticket/Elements/ShowAttachments:25 html/Work/Tickets/Elements/ShowTransaction:37 msgid "Attachments" msgstr "附件" @@ -923,11 +926,11 @@ msgstr "自动驳回表å•" msgid "AutoResolve" msgstr "自动完æˆè¡¨å•å¤„ç†" -#: etc/initialdata:224 +#: etc/initialdata:206 msgid "Autoreply" msgstr "自动回å¤" -#: etc/initialdata:90 +#: etc/initialdata:72 msgid "Autoreply To Requestors" msgstr "自动对申请人回å¤" @@ -935,7 +938,7 @@ msgstr "自动对申请人回å¤" msgid "AutoreplyToRequestors" msgstr "自动对申请人回å¤" -#: html/Edit/Rights/index.html:16 +#: html/Edit/Rights/index.html:17 msgid "Available Rights:" msgstr "æƒé™é¡¹ç›®åˆ—表:" @@ -964,19 +967,19 @@ msgstr "%1 çš„æ•°æ®é”™è¯¯" msgid "Bad transaction number for attachment. %1 should be %2\\n" msgstr "附件的处ç†å·ç 错误。%1 应为 %2\\n" -#: html/Admin/Elements/GroupTabs:38 html/Admin/Elements/QueueTabs:38 html/Admin/Elements/UserTabs:37 html/Edit/Global/autohandler:6 html/Edit/Queues/autohandler:17 html/Edit/Users/index.html:121 html/Ticket/Elements/Tabs:89 html/User/Elements/GroupTabs:37 +#: html/Admin/Elements/GroupTabs:38 html/Admin/Elements/QueueTabs:38 html/Admin/Elements/UserTabs:37 html/Edit/Global/autohandler:6 html/Edit/Queues/autohandler:21 html/Edit/Users/index.html:94 html/Ticket/Elements/Tabs:89 html/User/Elements/GroupTabs:37 msgid "Basics" msgstr "基本信æ¯" -#: html/Ticket/Update.html:81 html/Work/Tickets/Update.html:49 +#: html/Ticket/Update.html:81 html/Work/Tickets/Update.html:53 msgid "Bcc" msgstr "密件副本" -#: html/Admin/Elements/EditScrip:87 html/Admin/Global/GroupRights.html:84 html/Admin/Global/Template.html:45 html/Admin/Global/UserRights.html:53 html/Admin/Global/Workflow.html:46 html/Admin/Groups/GroupRights.html:72 html/Admin/Groups/Members.html:80 html/Admin/Groups/Modify.html:55 html/Admin/Groups/UserRights.html:54 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:44 html/Admin/Queues/UserRights.html:53 html/Admin/Queues/Workflow.html:44 html/User/Groups/Modify.html:55 +#: html/Admin/Elements/EditScrip:95 html/Admin/Global/GroupRights.html:84 html/Admin/Global/Template.html:45 html/Admin/Global/UserRights.html:53 html/Admin/Global/Workflow.html:46 html/Admin/Groups/GroupRights.html:72 html/Admin/Groups/Members.html:80 html/Admin/Groups/Modify.html:55 html/Admin/Groups/UserRights.html:54 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:44 html/Admin/Queues/UserRights.html:53 html/Admin/Queues/Workflow.html:44 html/User/Groups/Modify.html:55 msgid "Be sure to save your changes" msgstr "请别忘了储å˜ä¿®æ”¹ã€‚" -#: html/Elements/SelectDateRelation:33 lib/RT/CurrentUser.pm:321 +#: html/Elements/SelectDateRelation:33 lib/RT/CurrentUser.pm:320 msgid "Before" msgstr "早于" @@ -988,11 +991,11 @@ msgstr "开始ç¾æ ¸" msgid "Begin From " msgstr "起始日" -#: html/Edit/Users/Info:25 +#: NOT FOUND IN SOURCE msgid "Birthday" msgstr "生日" -#: etc/initialdata:220 +#: etc/initialdata:202 msgid "Blank" msgstr "空白模æ¿" @@ -1016,7 +1019,7 @@ msgstr "事业部" msgid "Business Unit:" msgstr "事业部:" -#: lib/RT/User_Overlay.pm:1411 +#: lib/RT/User_Overlay.pm:1529 msgid "Can not modify system users" msgstr "æ— æ³•æ›´æ”¹ç³»ç»Ÿä½¿ç”¨è€…" @@ -1032,11 +1035,11 @@ msgstr "ä¸èƒ½æ–°å¢žæ²¡æœ‰å称的自订å—段值" msgid "Can't link a ticket to itself" msgstr "申请å•ä¸èƒ½é“¾æŽ¥è‡ªå·±ã€‚" -#: lib/RT/Ticket_Overlay.pm:2816 +#: lib/RT/Ticket_Overlay.pm:2857 msgid "Can't merge into a merged ticket. You should never get this error" msgstr "ä¸èƒ½æ•´åˆè¿›å·²æ•´åˆè¿‡çš„申请å•ã€‚这个错误ä¸è¯¥å‘生。" -#: lib/RT/Ticket_Overlay.pm:2634 lib/RT/Ticket_Overlay.pm:2703 +#: lib/RT/Ticket_Overlay.pm:2659 lib/RT/Ticket_Overlay.pm:2738 msgid "Can't specifiy both base and target" msgstr "ä¸èƒ½åŒæ—¶æŒ‡å®šèµ·å§‹ç”³è¯·å•ä¸Žç›®çš„申请å•" @@ -1044,7 +1047,7 @@ msgstr "ä¸èƒ½åŒæ—¶æŒ‡å®šèµ·å§‹ç”³è¯·å•ä¸Žç›®çš„申请å•" msgid "Cancel" msgstr "å–消" -#: html/autohandler:113 +#: html/autohandler:126 #. ($msg) msgid "Cannot create user: %1" msgstr "æ— æ³•æ–°å¢žä½¿ç”¨è€…ï¼š%1" @@ -1061,7 +1064,7 @@ msgstr "分类管ç†" msgid "Category" msgstr "分类" -#: etc/initialdata:68 html/Admin/Queues/People.html:43 html/SelfService/Create.html:48 html/Ticket/Create.html:63 html/Ticket/Elements/EditPeople:50 html/Ticket/Elements/ShowPeople:34 html/Ticket/Update.html:44 html/Ticket/Update.html:76 html/Work/Tickets/Update.html:43 lib/RT/ACE_Overlay.pm:87 +#: etc/initialdata:50 html/Admin/Queues/People.html:43 html/SelfService/Create.html:48 html/Ticket/Create.html:63 html/Ticket/Elements/EditPeople:50 html/Ticket/Elements/ShowPeople:34 html/Ticket/Update.html:44 html/Ticket/Update.html:76 html/Work/Tickets/Elements/EditPeople:41 html/Work/Tickets/Elements/ShowLinks:6 html/Work/Tickets/Update.html:43 lib/RT/ACE_Overlay.pm:87 msgid "Cc" msgstr "副本" @@ -1081,11 +1084,11 @@ msgstr "修改申请å•" msgid "Change password" msgstr "更改å£ä»¤" -#: html/Edit/Global/Basic/Top:70 +#: html/Edit/Global/Basic/Top:79 msgid "ChangeOwnerUI" msgstr "å¯å¦é€‰æ‹©è¡¨å•æ‰¿åŠžäºº" -#: html/Ticket/Create.html:100 html/Ticket/Elements/EditCustomFieldEntries:35 html/Ticket/Update.html:90 html/Work/Tickets/Elements/ShowCustomFieldEntries:13 +#: html/SelfService/Update.html:39 html/Ticket/Create.html:100 html/Ticket/Elements/EditCustomFieldEntries:35 html/Ticket/Update.html:90 html/Work/Tickets/Elements/ShowCustomFieldEntries:14 msgid "Check box to delete" msgstr "é€‰æ‹©æ¬²åˆ é™¤çš„é¡¹ç›®" @@ -1093,11 +1096,11 @@ msgstr "é€‰æ‹©æ¬²åˆ é™¤çš„é¡¹ç›®" msgid "Check box to revoke right" msgstr "选择欲撤消的æƒåˆ©" -#: html/Ticket/Create.html:182 html/Ticket/Elements/BulkLinks:42 html/Ticket/Elements/EditLinks:130 html/Ticket/Elements/EditLinks:68 html/Ticket/Elements/ShowLinks:56 html/Work/Search/BulkLinks:18 +#: html/Ticket/Create.html:183 html/Ticket/Elements/BulkLinks:42 html/Ticket/Elements/EditLinks:113 html/Ticket/Elements/EditLinks:63 html/Ticket/Elements/ShowLinks:56 html/Work/Search/BulkLinks:18 html/Work/Tickets/Elements/EditLinks:117 html/Work/Tickets/Elements/EditLinks:56 html/Work/Tickets/Elements/ShowMembers:4 msgid "Children" msgstr "å申请å•" -#: html/Edit/Elements/PickUsers:21 html/Edit/Global/UserRight/List:8 html/Edit/Global/UserRight/Top:19 html/Edit/Users/List:6 html/Edit/Users/Top:18 +#: html/Edit/Elements/PickUsers:21 html/Edit/Global/UserRight/List:8 html/Edit/Global/UserRight/Top:19 msgid "Chinese Name" msgstr "ä¸æ–‡å§“å" @@ -1105,11 +1108,15 @@ msgstr "ä¸æ–‡å§“å" msgid "Chinese/English" msgstr "ä¸è‹±æ–‡" -#: html/Admin/Elements/ModifyUser:79 html/Admin/Users/Modify.html:131 html/User/Prefs.html:91 html/Work/Preferences/Info:80 +#: html/Admin/Elements/ModifyUser:79 html/Admin/Users/Modify.html:131 html/User/Prefs.html:122 html/Work/Preferences/Info:83 msgid "City" msgstr "所在城市" -#: html/Ticket/Elements/ShowDates:46 +#: html/Edit/Elements/104Top:30 +msgid "ClassicUI" +msgstr "ä¼ ç»ŸæŽ¥å£" + +#: html/Ticket/Elements/ShowDates:47 msgid "Closed" msgstr "已解决" @@ -1121,7 +1128,7 @@ msgstr "已解决的申请å•" msgid "Closed tickets" msgstr "已解决的申请å•" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:181 html/Edit/Global/Workflow/Action:58 html/Edit/Global/Workflow/Condition:51 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:181 html/Edit/Global/Workflow/Action:54 html/Edit/Global/Workflow/Condition:52 msgid "Code" msgstr "执行程åºç " @@ -1129,7 +1136,7 @@ msgstr "执行程åºç " msgid "Command not understood!\\n" msgstr "æŒ‡ä»¤æ— æ³•è¾¨è¯†ï¼\\n" -#: html/Ticket/Elements/ShowTransaction:166 html/Ticket/Elements/Tabs:152 html/Work/Search/Bulk.html:89 html/Work/Tickets/Display.html:37 html/Work/Tickets/Elements/ShowTransaction:112 html/Work/Tickets/Elements/ShowTransaction:27 +#: html/Ticket/Elements/ShowTransaction:178 html/Ticket/Elements/Tabs:152 html/Work/Search/Bulk.html:89 html/Work/Tickets/Display.html:60 html/Work/Tickets/Elements/ShowTransaction:118 html/Work/Tickets/Elements/ShowTransaction:32 msgid "Comment" msgstr "评论" @@ -1149,7 +1156,7 @@ msgstr "对申请å•æ出评论" msgid "CommentOnTicket" msgstr "评论申请å•" -#: html/Admin/Elements/ModifyUser:34 html/Work/Tickets/Update.html:59 +#: html/Admin/Elements/ModifyUser:34 html/Work/Tickets/Elements/AddContent:7 msgid "Comments" msgstr "评论" @@ -1166,11 +1173,11 @@ msgstr "评论(ä¸é€ç»™ç”³è¯·äºº)" msgid "Comments about %1" msgstr "对 %1 的评论" -#: html/Admin/Users/Modify.html:184 html/Ticket/Elements/ShowRequestor:43 +#: html/Admin/Users/Modify.html:184 html/Edit/Users/Info:46 html/Ticket/Elements/ShowRequestor:43 msgid "Comments about this user" msgstr "使用者æè¿°" -#: lib/RT/Transaction_Overlay.pm:543 +#: lib/RT/Transaction_Overlay.pm:501 msgid "Comments added" msgstr "新增评论完毕" @@ -1182,10 +1189,14 @@ msgstr "确认" msgid "Commit Stubbed" msgstr "消除更动完毕" -#: html/Edit/Users/Info:42 +#: NOT FOUND IN SOURCE msgid "Company Name" msgstr "å…¬å¸å称" +#: html/Edit/Global/Basic/Top:85 +msgid "CompanySpecific" +msgstr "å„å…¬å¸ç‹¬ç«‹æ˜¾ç¤º" + #: NOT FOUND IN SOURCE msgid "Compile Restrictions" msgstr "设定查询æ¡ä»¶" @@ -1198,11 +1209,11 @@ msgstr "æ¡ä»¶" msgid "Condition matches..." msgstr "符åˆæ¡ä»¶..." -#: lib/RT/Scrip_Overlay.pm:159 +#: lib/RT/Scrip_Overlay.pm:164 msgid "Condition not found" msgstr "未找到符åˆçš„现况" -#: html/Edit/Global/GroupRight/Top:26 html/Edit/Global/UserRight/Top:45 html/Edit/Groups/Member:57 html/Elements/Tabs:49 +#: html/Edit/Global/GroupRight/Top:26 html/Edit/Global/UserRight/Top:45 html/Edit/Groups/Member:56 html/Elements/Tabs:49 msgid "Configuration" msgstr "设定" @@ -1214,7 +1225,7 @@ msgstr "确认å£ä»¤" msgid "Confirm Password" msgstr "å£ä»¤ç¡®è®¤" -#: html/Work/Approvals/Display.html:25 html/Work/Tickets/Create.html:153 html/Work/Tickets/Create.html:165 html/Work/Tickets/Update.html:81 +#: html/Work/Approvals/Display.html:25 html/Work/Tickets/Create.html:154 html/Work/Tickets/Create.html:168 html/Work/Tickets/Update.html:77 msgid "Confirm Submit" msgstr "确定é€å‡º" @@ -1238,7 +1249,7 @@ msgstr "内容" msgid "Coould not create group" msgstr "æ— æ³•æ–°å¢žç¾¤ç»„" -#: html/Edit/Elements/104Buttons:74 +#: html/Edit/Elements/104Buttons:85 msgid "Copy" msgstr "å¤åˆ¶" @@ -1246,7 +1257,7 @@ msgstr "å¤åˆ¶" msgid "Copy Field From:" msgstr "欲å¤åˆ¶å—段:" -#: etc/initialdata:282 +#: etc/initialdata:271 msgid "Correspondence" msgstr "回å¤" @@ -1254,7 +1265,7 @@ msgstr "回å¤" msgid "Correspondence Address" msgstr "申请å•å›žå¤åœ°å€" -#: lib/RT/Transaction_Overlay.pm:539 +#: lib/RT/Transaction_Overlay.pm:497 msgid "Correspondence added" msgstr "新增申请å•å›žå¤" @@ -1262,7 +1273,7 @@ msgstr "新增申请å•å›žå¤" msgid "Correspondence not recorded" msgstr "未纪录申请å•å›žå¤" -#: lib/RT/Ticket_Overlay.pm:3561 +#: lib/RT/Ticket_Overlay.pm:3608 msgid "Could not add new custom field value for ticket. " msgstr "ä¸èƒ½æ–°å¢žè‡ªè®¢å—段的值 " @@ -1270,11 +1281,11 @@ msgstr "ä¸èƒ½æ–°å¢žè‡ªè®¢å—段的值 " msgid "Could not add new custom field value for ticket. %1 " msgstr "ä¸èƒ½æ–°å¢žè‡ªè®¢å—段的值。%1 " -#: lib/RT/Ticket_Overlay.pm:3067 lib/RT/Ticket_Overlay.pm:3075 lib/RT/Ticket_Overlay.pm:3092 +#: lib/RT/Ticket_Overlay.pm:3108 lib/RT/Ticket_Overlay.pm:3116 lib/RT/Ticket_Overlay.pm:3133 msgid "Could not change owner. " msgstr "ä¸èƒ½æ›´æ”¹æ‰¿åŠžäººã€‚ " -#: html/Admin/Elements/EditCustomField:84 html/Admin/Elements/EditCustomFields:165 html/Edit/Global/CustomField/index.html:117 +#: html/Admin/Elements/EditCustomField:84 html/Admin/Elements/EditCustomFields:164 html/Edit/Global/CustomField/index.html:120 #. ($msg) msgid "Could not create CustomField" msgstr "æ— æ³•æ–°å¢žè‡ªè®¢å—段" @@ -1289,20 +1300,25 @@ msgstr "æ— æ³•å»ºç«‹è®¯æ¯é€šçŸ¥" msgid "Could not create Template" msgstr "æ— æ³•å»ºç«‹é€šçŸ¥æ¨¡æ¿" -#: html/User/Groups/Modify.html:76 lib/RT/Group_Overlay.pm:473 lib/RT/Group_Overlay.pm:480 +#: html/User/Groups/Modify.html:76 lib/RT/Group_Overlay.pm:471 lib/RT/Group_Overlay.pm:478 msgid "Could not create group" msgstr "æ— æ³•æ–°å¢žç¾¤ç»„" +#: html/Edit/Elements/Index:89 +#. ($msg) +msgid "Could not create item" +msgstr "æ— æ³•æ–°å¢žé¡¹ç›®" + #: html/Admin/Global/Template.html:74 html/Admin/Queues/Template.html:71 #. ($msg) msgid "Could not create template: %1" msgstr "æ— æ³•æ–°å¢žæ¨¡æ¿ï¼š%1" -#: lib/RT/Ticket_Overlay.pm:1081 lib/RT/Ticket_Overlay.pm:334 +#: lib/RT/Ticket_Overlay.pm:1118 lib/RT/Ticket_Overlay.pm:353 msgid "Could not create ticket. Queue not set" msgstr "æ— æ³•æ–°å¢žç”³è¯·å•ã€‚尚未指定表å•ã€‚" -#: lib/RT/User_Overlay.pm:267 lib/RT/User_Overlay.pm:279 lib/RT/User_Overlay.pm:297 lib/RT/User_Overlay.pm:481 +#: lib/RT/User_Overlay.pm:271 lib/RT/User_Overlay.pm:284 lib/RT/User_Overlay.pm:302 lib/RT/User_Overlay.pm:488 msgid "Could not create user" msgstr "æ— æ³•æ–°å¢žä½¿ç”¨è€…" @@ -1323,11 +1339,11 @@ msgstr "找ä¸åˆ°ç¼–å· %1 的申请å•" msgid "Could not find group %1." msgstr "找ä¸åˆ°ç¾¤ç»„ %1。" -#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1430 +#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1448 msgid "Could not find or create that user" msgstr "找ä¸åˆ°æˆ–æ— æ³•æ–°å¢žè¯¥å使用者" -#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1509 +#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1527 msgid "Could not find that principal" msgstr "找ä¸åˆ°è¯¥å•ä½" @@ -1335,8 +1351,7 @@ msgstr "找ä¸åˆ°è¯¥å•ä½" msgid "Could not find user %1." msgstr "找ä¸åˆ°ä½¿ç”¨è€… %1。" -#: html/Admin/Groups/Members.html:87 html/Edit/Users/index.html:83 html/User/Groups/Members.html:89 html/User/Groups/Modify.html:81 -#. ( . $GroupId) +#: html/Admin/Groups/Members.html:87 html/User/Groups/Members.html:89 html/User/Groups/Modify.html:81 msgid "Could not load group" msgstr "æ— æ³•åŠ è½½ç¾¤ç»„" @@ -1345,7 +1360,7 @@ msgstr "æ— æ³•åŠ è½½ç¾¤ç»„" msgid "Could not make that principal a %1 for this queue" msgstr "æ— æ³•å°†è¯¥å•ä½è®¾ä¸ºæ¤è¡¨å•çš„ %1。" -#: lib/RT/Ticket_Overlay.pm:1451 +#: lib/RT/Ticket_Overlay.pm:1469 #. ($self->loc($args{'Type'})) msgid "Could not make that principal a %1 for this ticket" msgstr "æ— æ³•å°†è¯¥å•ä½è®¾ä¸ºæ¤ç”³è¯·å•çš„ %1。" @@ -1355,16 +1370,16 @@ msgstr "æ— æ³•å°†è¯¥å•ä½è®¾ä¸ºæ¤ç”³è¯·å•çš„ %1。" msgid "Could not remove that principal as a %1 for this queue" msgstr "æ— æ³•å°†å•ä½ %1 从表å•ç§»é™¤ã€‚" -#: lib/RT/Ticket_Overlay.pm:1567 +#: lib/RT/Ticket_Overlay.pm:1585 #. ($args{'Type'}) msgid "Could not remove that principal as a %1 for this ticket" msgstr "æ— æ³•å°†å•ä½ %1 从申请å•ç§»é™¤ã€‚" -#: lib/RT/Group_Overlay.pm:984 +#: lib/RT/Group_Overlay.pm:982 msgid "Couldn't add member to group" msgstr "æ— æ³•æ–°å¢žæˆå‘˜è‡³ç¾¤ç»„" -#: lib/RT/Ticket_Overlay.pm:3571 lib/RT/Ticket_Overlay.pm:3627 +#: lib/RT/Ticket_Overlay.pm:3618 lib/RT/Ticket_Overlay.pm:3674 #. ($Msg) msgid "Couldn't create a transaction: %1" msgstr "æ— æ³•æ–°å¢žæ›´åŠ¨æŠ¥å‘Š" @@ -1377,11 +1392,11 @@ msgstr "æ— æ³•ä»Ž gpg 回函辨识出该采å–的行动\\n" msgid "Couldn't find group\\n" msgstr "找ä¸åˆ°ç¾¤ç»„\\n" -#: lib/RT/Interface/Web.pm:902 +#: lib/RT/Interface/Web.pm:962 msgid "Couldn't find row" msgstr "找ä¸åˆ°æ¤åˆ—æ•°æ®" -#: lib/RT/Group_Overlay.pm:958 +#: lib/RT/Group_Overlay.pm:956 msgid "Couldn't find that principal" msgstr "找ä¸åˆ°è¯¥å•ä½" @@ -1414,9 +1429,10 @@ msgstr "æ— æ³•åŠ è½½ RT 设定档 '%1' %2" msgid "Couldn't load Scrips." msgstr "æ— æ³•åŠ è½½æ‰‹ç»ã€‚" -#: html/Admin/Groups/GroupRights.html:87 html/Admin/Groups/UserRights.html:74 html/Edit/Global/GroupRight/Add.html:54 html/Edit/Global/UserRight/Add.html:23 html/Edit/Groups/Member:121 html/Edit/Groups/Members/Add.html:44 html/Edit/Rights/index.html:57 -#. ($Group) +#: html/Admin/Groups/GroupRights.html:87 html/Admin/Groups/UserRights.html:74 html/Edit/Global/GroupRight/Add.html:55 html/Edit/Global/GroupRight/Add.html:60 html/Edit/Global/UserRight/Add.html:25 html/Edit/Global/UserRight/Add.html:30 html/Edit/Groups/Member:120 html/Edit/Groups/Members/Add.html:43 html/Edit/Rights/index.html:58 html/Edit/Rights/index.html:63 #. ($ObjectGroup) +#. ($Report) +#. ($Group) #. ($id) msgid "Couldn't load group %1" msgstr "æ— æ³•åŠ è½½æ‰‹ç» %1" @@ -1425,12 +1441,12 @@ msgstr "æ— æ³•åŠ è½½æ‰‹ç» %1" msgid "Couldn't load link" msgstr "æ— æ³•åŠ è½½é“¾æŽ¥ã€‚" -#: html/Admin/Elements/EditCustomFields:146 html/Admin/Queues/People.html:120 +#: html/Admin/Elements/EditCustomFields:145 html/Admin/Queues/CustomFields.html:35 html/Admin/Queues/People.html:120 #. ($id) msgid "Couldn't load queue" msgstr "æ— æ³•åŠ è½½è¡¨å•" -#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:71 html/Edit/Global/GroupRight/Add.html:50 html/Edit/Global/GroupRight/index.html:81 html/Edit/Global/UserRight/Add.html:19 html/Edit/Global/UserRight/index.html:83 html/Edit/Rights/index.html:53 +#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:71 html/Edit/Global/GroupRight/Add.html:51 html/Edit/Global/GroupRight/index.html:82 html/Edit/Global/GroupRight/index.html:87 html/Edit/Global/UserRight/Add.html:21 html/Edit/Global/UserRight/index.html:83 html/Edit/Global/UserRight/index.html:88 html/Edit/Rights/index.html:54 #. ($Queue) #. ($id) msgid "Couldn't load queue %1" @@ -1449,16 +1465,16 @@ msgstr "æ— æ³•åŠ è½½æ¨¡æ¿" msgid "Couldn't load that user (%1)" msgstr "æ— æ³•åŠ è½½è¯¥å使用者(%1)" -#: html/SelfService/Display.html:108 +#: html/SelfService/Display.html:114 #. ($id) msgid "Couldn't load ticket '%1'" msgstr "æ— æ³•åŠ è½½ç”³è¯·å• '%1'" -#: html/Admin/Elements/ModifyUser:85 html/Admin/Users/Modify.html:148 html/User/Prefs.html:97 html/Work/Preferences/Info:86 +#: html/Admin/Elements/ModifyUser:85 html/Admin/Users/Modify.html:148 html/User/Prefs.html:134 html/Work/Preferences/Info:89 msgid "Country" msgstr "国家" -#: html/Admin/Elements/CreateUserCalled:25 html/Edit/Elements/PopHeader:29 html/Edit/Global/GroupRight/Add.html:18 html/Ticket/Create.html:134 html/Ticket/Create.html:194 +#: html/Admin/Elements/CreateUserCalled:25 html/Edit/Elements/PopHeader:33 html/Edit/Global/GroupRight/Add.html:19 html/Ticket/Create.html:134 html/Ticket/Create.html:195 msgid "Create" msgstr "新增" @@ -1466,7 +1482,7 @@ msgstr "新增" msgid "Create Subgroup:" msgstr "新增å群组:" -#: etc/initialdata:145 +#: etc/initialdata:127 msgid "Create Tickets" msgstr "新增申请å•" @@ -1523,7 +1539,7 @@ msgstr "新增模æ¿" msgid "Create a new ticket" msgstr "新增申请å•" -#: html/Admin/Users/Modify.html:213 html/Admin/Users/Modify.html:240 +#: html/Admin/Users/Modify.html:213 html/Admin/Users/Modify.html:242 msgid "Create a new user" msgstr "新增使用者" @@ -1572,7 +1588,7 @@ msgstr "新增失败:%1/%2/%3" msgid "Create new item" msgstr "建立新项目" -#: etc/initialdata:147 +#: etc/initialdata:129 msgid "Create new tickets based on this scrip's template" msgstr "ä¾æ®æ¤é¡¹æ‰‹ç»å†…的模版,新增申请å•" @@ -1608,7 +1624,7 @@ msgstr "新增ã€åˆ 除åŠæ›´æ”¹ä½¿ç”¨è€…" msgid "CreateTicket" msgstr "新增申请å•" -#: html/Elements/SelectDateType:25 html/Ticket/Elements/ShowDates:26 lib/RT/Ticket_Overlay.pm:1175 +#: html/Elements/SelectDateType:25 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1212 msgid "Created" msgstr "新增日" @@ -1642,11 +1658,11 @@ msgstr "现有自订å—段" msgid "Current Groups:" msgstr "现有群组列表:" -#: html/Ticket/Elements/EditLinks:27 +#: html/Ticket/Elements/EditLinks:27 html/Work/Tickets/Elements/EditLinks:10 msgid "Current Relationships" msgstr "现有关系" -#: html/Edit/Rights/index.html:19 +#: html/Edit/Rights/index.html:20 msgid "Current Rights:" msgstr "现有æƒé™ï¼š" @@ -1654,7 +1670,7 @@ msgstr "现有æƒé™ï¼š" msgid "Current Scrips" msgstr "现有手ç»" -#: html/Work/Tickets/Create.html:48 html/Work/Tickets/Elements/ShowBasics:39 +#: html/Work/Tickets/Create.html:49 html/Work/Tickets/Elements/ShowBasics:47 msgid "Current Status" msgstr "ç›®å‰çŠ¶æ€" @@ -1662,6 +1678,10 @@ msgstr "ç›®å‰çŠ¶æ€" msgid "Current Templates" msgstr "现有模æ¿" +#: html/Work/Tickets/Elements/EditPeople:9 +msgid "Current Watchers" +msgstr "现有视察员" + #: html/Admin/Groups/Members.html:38 html/User/Groups/Members.html:41 msgid "Current members" msgstr "现有æˆå‘˜" @@ -1674,7 +1694,7 @@ msgstr "现有æƒé™" msgid "Current search criteria" msgstr "现有查询æ¡ä»¶" -#: html/Admin/Queues/People.html:40 html/Ticket/Elements/EditPeople:44 +#: html/Admin/Queues/People.html:40 html/Ticket/Elements/EditPeople:44 html/Work/Tickets/Elements/EditPeople:32 msgid "Current watchers" msgstr "现有视察员" @@ -1683,7 +1703,7 @@ msgstr "现有视察员" msgid "Custom Field #%1" msgstr "自订å—段 #%1" -#: html/Admin/Elements/QueueTabs:52 html/Admin/Elements/SystemTabs:39 html/Admin/Global/index.html:49 html/Edit/Global/autohandler:7 html/Edit/Queues/autohandler:18 html/Ticket/Elements/ShowSummary:35 +#: html/Admin/Elements/QueueTabs:52 html/Admin/Elements/SystemTabs:39 html/Admin/Global/index.html:49 html/Edit/Global/autohandler:7 html/Edit/Queues/autohandler:22 html/Ticket/Elements/ShowSummary:35 msgid "Custom Fields" msgstr "自订å—段" @@ -1703,31 +1723,31 @@ msgstr "动作å‰æ‰§è¡Œç¨‹åº" msgid "Custom condition" msgstr "自订æ¡ä»¶" -#: lib/RT/Tickets_Overlay.pm:1618 +#: lib/RT/Tickets_Overlay.pm:1637 #. ($CF->Name , $args{OPERATOR} , $args{VALUE}) msgid "Custom field %1 %2 %3" msgstr "自订å—段 %1 %2 %3" -#: lib/RT/Tickets_Overlay.pm:1613 +#: lib/RT/Tickets_Overlay.pm:1632 #. ($CF->Name) msgid "Custom field %1 has a value." msgstr "自订å—段 %1 已有值" -#: lib/RT/Tickets_Overlay.pm:1610 +#: lib/RT/Tickets_Overlay.pm:1629 #. ($CF->Name) msgid "Custom field %1 has no value." msgstr "自订å—段 %1 没有值" -#: lib/RT/Ticket_Overlay.pm:3463 +#: lib/RT/Ticket_Overlay.pm:3510 #. ($args{'Field'}) msgid "Custom field %1 not found" msgstr "找ä¸åˆ°è‡ªè®¢å—段 %1" -#: html/Admin/Elements/EditCustomFields:196 +#: html/Admin/Elements/EditCustomFields:195 msgid "Custom field deleted" msgstr "自订å—æ®µå·²åˆ é™¤" -#: lib/RT/Ticket_Overlay.pm:3613 +#: lib/RT/Ticket_Overlay.pm:3660 msgid "Custom field not found" msgstr "找ä¸åˆ°è‡ªè®¢å—段" @@ -1752,7 +1772,7 @@ msgstr "找ä¸åˆ°è‡ªè®¢å—段值" msgid "Custom field value deleted" msgstr "自订å—æ®µå€¼åˆ é™¤æˆåŠŸ" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:145 html/Edit/Global/Workflow/Owner.html:90 lib/RT/Transaction_Overlay.pm:548 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:145 html/Edit/Global/Workflow/Owner.html:90 lib/RT/Transaction_Overlay.pm:505 lib/RT/Transaction_Vendor.pm:5 msgid "CustomField" msgstr "自订å—段" @@ -1760,11 +1780,19 @@ msgstr "自订å—段" msgid "Data error" msgstr "æ•°æ®é”™è¯¯" +#: html/Edit/Global/Basic/Top:77 +msgid "DatabaseBindRemote" +msgstr "容许外部è”机" + +#: html/Edit/Global/Basic/Top:75 +msgid "DatabaseName" +msgstr "MySQLæ•°æ®åº“" + #: NOT FOUND IN SOURCE msgid "Date of Departure" msgstr "出å‘日期" -#: html/SelfService/Display.html:38 html/Ticket/Create.html:160 html/Ticket/Elements/ShowSummary:54 html/Ticket/Elements/Tabs:92 html/Ticket/ModifyAll.html:43 html/Work/Tickets/Elements/ShowTransaction:14 +#: html/SelfService/Display.html:38 html/Ticket/Create.html:160 html/Ticket/Elements/ShowSummary:54 html/Ticket/Elements/Tabs:92 html/Ticket/ModifyAll.html:43 html/Work/Tickets/Elements/ShowTransaction:17 msgid "Dates" msgstr "日期" @@ -1781,34 +1809,46 @@ msgid "December" msgstr "å二月" #: NOT FOUND IN SOURCE +msgid "Default Approval" +msgstr "预设ç¾æ ¸" + +#: NOT FOUND IN SOURCE msgid "Default Autoresponse Template" msgstr "预设自动å“应模æ¿" -#: etc/initialdata:225 +#: etc/initialdata:207 msgid "Default Autoresponse template" msgstr "预设自动å“应模æ¿" -#: etc/initialdata:304 +#: html/Edit/Global/CustomField/Top:46 +msgid "Default Value" +msgstr "预设值" + +#: etc/initialdata:281 msgid "Default admin comment template" msgstr "预设管ç†å‘˜è¯„论模æ¿" -#: etc/initialdata:262 +#: etc/initialdata:260 msgid "Default admin correspondence template" msgstr "预设管ç†å‘˜å›žå¤æ¨¡æ¿" -#: etc/initialdata:283 +#: etc/initialdata:272 msgid "Default correspondence template" msgstr "预设回å¤æ¨¡æ¿" -#: etc/initialdata:240 +#: etc/initialdata:238 msgid "Default transaction template" msgstr "预设更动模æ¿" -#: lib/RT/Transaction_Overlay.pm:643 +#: lib/RT/Transaction_Overlay.pm:491 #. ($type, $self->Field, $self->OldValue, $self->NewValue) msgid "Default: %1/%2 changed from %3 to %4" msgstr "预设:%1/%2 已自 %3 改为 %4" +#: NOT FOUND IN SOURCE +msgid "DefaultApproval" +msgstr "预设ç¾æ ¸" + #: html/User/Delegation.html:24 html/User/Delegation.html:27 msgid "Delegate rights" msgstr "代表团æƒé™" @@ -1837,7 +1877,7 @@ msgstr "代ç†è¡¨å•ï¼š" msgid "Delegated Type" msgstr "代ç†è¡¨å•ç§ç±»" -#: html/Edit/Users/index.html:125 html/Work/Delegates/Info:31 html/Work/Delegates/List:8 html/Work/Elements/Tab:39 html/Work/Overview/Info:28 +#: html/Edit/Users/index.html:98 html/Work/Delegates/Info:31 html/Work/Delegates/List:8 html/Work/Elements/Tab:41 html/Work/Overview/Info:28 msgid "Delegates" msgstr "代ç†äºº" @@ -1881,10 +1921,14 @@ msgstr "代ç†äººç¾¤ç»„" msgid "Delegation Rights" msgstr "代ç†äººæƒé™" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:113 html/Edit/Elements/104Buttons:73 html/Work/Search/index.html:48 html/Work/Search/index.html:48 +#: html/Admin/Elements/EditScrips:53 html/Admin/Elements/ModifyTemplateAsWorkflow:113 html/Edit/Elements/104Buttons:84 html/Work/Search/index.html:48 html/Work/Search/index.html:48 msgid "Delete" msgstr "åˆ é™¤" +#: html/Admin/Elements/EditScrips:52 +msgid "Delete selected scrips" +msgstr "åˆ é™¤æŒ‡å®šçš„æ‰‹ç»" + #: lib/RT/Queue_Overlay.pm:88 msgid "Delete tickets" msgstr "åˆ é™¤ç”³è¯·å•" @@ -1893,7 +1937,7 @@ msgstr "åˆ é™¤ç”³è¯·å•" msgid "DeleteTicket" msgstr "åˆ é™¤ç”³è¯·å•" -#: lib/RT/Transaction_Overlay.pm:187 +#: lib/RT/Transaction_Overlay.pm:136 msgid "Deleting this object could break referential integrity" msgstr "åˆ é™¤æ¤å¯¹è±¡å¯èƒ½ç ´åå‚考完整性" @@ -1901,7 +1945,7 @@ msgstr "åˆ é™¤æ¤å¯¹è±¡å¯èƒ½ç ´åå‚考完整性" msgid "Deleting this object would break referential integrity" msgstr "åˆ é™¤æ¤å¯¹è±¡å¯èƒ½ç ´åå‚考完整性" -#: lib/RT/User_Overlay.pm:497 +#: lib/RT/User_Overlay.pm:504 msgid "Deleting this object would violate referential integrity" msgstr "åˆ é™¤æ¤å¯¹è±¡ä¼šè¿åå‚考完整性" @@ -1921,11 +1965,11 @@ msgstr "驳回" msgid "Department" msgstr "部门" -#: html/Edit/Global/UserRight/List:12 html/Edit/Global/UserRight/Top:13 html/Edit/Users/List:10 html/Edit/Users/Top:12 +#: html/Edit/Global/UserRight/List:12 html/Edit/Global/UserRight/Top:13 msgid "Department ID" msgstr "部门代ç " -#: html/Edit/Global/UserRight/List:11 html/Edit/Global/UserRight/Top:49 html/Edit/Users/List:9 html/Edit/Users/Top:48 html/Work/Delegates/Info:78 html/Work/Overview/Info:60 +#: html/Edit/Global/UserRight/List:11 html/Edit/Global/UserRight/Top:49 html/Work/Delegates/Info:78 html/Work/Overview/Info:60 msgid "Department Name" msgstr "部门å称" @@ -1949,7 +1993,7 @@ msgstr "请å‡å•" msgid "Departure Until" msgstr "差旅截æ¢æ—¥" -#: html/Ticket/Create.html:180 html/Ticket/Elements/BulkLinks:34 html/Ticket/Elements/EditLinks:122 html/Ticket/Elements/EditLinks:46 html/Ticket/Elements/ShowDependencies:31 html/Ticket/Elements/ShowLinks:36 html/Work/Search/BulkLinks:10 +#: html/Ticket/Create.html:181 html/Ticket/Elements/BulkLinks:34 html/Ticket/Elements/EditLinks:105 html/Ticket/Elements/EditLinks:44 html/Ticket/Elements/ShowDependencies:31 html/Ticket/Elements/ShowLinks:36 html/Work/Search/BulkLinks:10 html/Work/Tickets/Elements/EditLinks:109 html/Work/Tickets/Elements/EditLinks:34 html/Work/Tickets/Elements/ShowLinks:21 msgid "Depended on by" msgstr "å¯æŽ¥ç»å¤„ç†çš„申请å•" @@ -1957,7 +2001,27 @@ msgstr "å¯æŽ¥ç»å¤„ç†çš„申请å•" msgid "Dependencies: \\n" msgstr "附属性:\\n" -#: html/Elements/SelectLinkType:26 html/Ticket/Create.html:179 html/Ticket/Elements/BulkLinks:30 html/Ticket/Elements/EditLinks:118 html/Ticket/Elements/EditLinks:35 html/Ticket/Elements/ShowDependencies:24 html/Ticket/Elements/ShowLinks:26 html/Work/Search/BulkLinks:6 +#: lib/RT/Transaction_Overlay.pm:585 +#. ($value) +msgid "Dependency by %1 added" +msgstr "å·²åŠ å…¥å¯æŽ¥ç»å¤„ç†çš„ç”³è¯·å• %1" + +#: lib/RT/Transaction_Overlay.pm:622 +#. ($value) +msgid "Dependency by %1 deleted" +msgstr "已移除å¯æŽ¥ç»å¤„ç†çš„ç”³è¯·å• %1" + +#: lib/RT/Transaction_Overlay.pm:582 +#. ($value) +msgid "Dependency on %1 added" +msgstr "å·²åŠ å…¥éœ€å…ˆå¤„ç†çš„ç”³è¯·å• %1" + +#: lib/RT/Transaction_Overlay.pm:619 +#. ($value) +msgid "Dependency on %1 deleted" +msgstr "已移除需先处ç†çš„ç”³è¯·å• %1" + +#: html/Elements/SelectLinkType:26 html/Ticket/Create.html:180 html/Ticket/Elements/BulkLinks:30 html/Ticket/Elements/EditLinks:101 html/Ticket/Elements/EditLinks:35 html/Ticket/Elements/ShowDependencies:24 html/Ticket/Elements/ShowLinks:26 html/Work/Search/BulkLinks:6 html/Work/Tickets/Elements/EditLinks:105 html/Work/Tickets/Elements/EditLinks:23 html/Work/Tickets/Elements/ShowLinks:16 msgid "Depends on" msgstr "需先处ç†" @@ -1973,7 +2037,7 @@ msgstr "递å‡" msgid "Describe the issue below" msgstr "在以下å—段æ述主题" -#: html/Admin/Elements/AddCustomFieldValue:35 html/Admin/Elements/EditCustomField:38 html/Admin/Elements/EditScrip:33 html/Admin/Elements/ModifyQueue:35 html/Admin/Elements/ModifyTemplate:35 html/Admin/Elements/ModifyTemplateAsWorkflow:192 html/Admin/Groups/Modify.html:48 html/Admin/Queues/Modify.html:47 html/Edit/Global/Workflow/Action:14 html/Elements/SelectGroups:26 html/User/Groups/Modify.html:48 html/Work/Preferences/Info:98 +#: html/Admin/Elements/AddCustomFieldValue:35 html/Admin/Elements/EditCustomField:38 html/Admin/Elements/EditScrip:33 html/Admin/Elements/ModifyQueue:35 html/Admin/Elements/ModifyTemplate:35 html/Admin/Elements/ModifyTemplateAsWorkflow:192 html/Admin/Groups/Modify.html:48 html/Admin/Queues/Modify.html:47 html/Edit/Elements/SelectQueues:4 html/Edit/Global/Workflow/Action:13 html/Elements/SelectGroups:26 html/User/Groups/Modify.html:48 msgid "Description" msgstr "æè¿°" @@ -1985,7 +2049,7 @@ msgstr "ç»åŠžä¸šåŠ¡è¯´æ˜Ž" msgid "Description:" msgstr "æ述:" -#: html/Work/Tickets/Create.html:108 html/Work/Tickets/Elements/EditCustomFields:39 html/Work/Tickets/Elements/ShowCustomFields:41 +#: html/Work/Tickets/Create.html:132 html/Work/Tickets/Create.html:84 html/Work/Tickets/Elements/EditCustomFields:13 html/Work/Tickets/Elements/EditCustomFields:61 html/Work/Tickets/Elements/ShowCustomFields:14 html/Work/Tickets/Elements/ShowCustomFields:53 msgid "Details" msgstr "细节" @@ -1993,15 +2057,15 @@ msgstr "细节" msgid "Direct" msgstr "直接" -#: html/Edit/Users/Info:31 +#: NOT FOUND IN SOURCE msgid "Disability" msgstr "残障身分" -#: html/Edit/Users/Info:29 +#: NOT FOUND IN SOURCE msgid "Disability Type" msgstr "残障类别" -#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:19 html/Edit/Queues/Basic/Top:70 html/Edit/Queues/List:13 html/Work/Delegates/Info:48 html/Work/Delegates/Info:53 html/Work/Delegates/List:12 html/Work/Overview/Info:42 +#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:19 html/Edit/Queues/Basic/Top:69 html/Edit/Queues/List:15 html/Edit/Queues/List:27 html/Work/Delegates/Info:48 html/Work/Delegates/Info:53 html/Work/Delegates/List:12 html/Work/Overview/Info:42 msgid "Disabled" msgstr "åœç”¨" @@ -2037,7 +2101,7 @@ msgstr "å…许一切æ“作" msgid "Don't refresh this page." msgstr "ä¸æ›´æ–°æ¤é¡µé¢ã€‚" -#: html/Search/Elements/PickRestriction:113 html/Work/Search/PickRestriction:95 +#: html/Search/Elements/PickRestriction:113 html/Work/Search/PickRestriction:101 msgid "Don't show search results" msgstr "ä¸æ˜¾ç¤ºæŸ¥è¯¢ç»“æžœ" @@ -2045,7 +2109,7 @@ msgstr "ä¸æ˜¾ç¤ºæŸ¥è¯¢ç»“æžœ" msgid "Down" msgstr "下一页" -#: html/Ticket/Elements/ShowTransaction:92 +#: html/Ticket/Elements/ShowTransaction:103 msgid "Download" msgstr "下载" @@ -2053,7 +2117,7 @@ msgstr "下载" msgid "Dr." msgstr "åšå£«" -#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:44 html/Ticket/Elements/ShowDates:42 lib/RT/Ticket_Overlay.pm:1179 +#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:44 html/Ticket/Elements/ShowDates:43 html/Work/Tickets/Elements/EditBasics:54 lib/RT/Ticket_Overlay.pm:1216 msgid "Due" msgstr "到期日" @@ -2070,7 +2134,7 @@ msgstr "æ— æ³•è§£è¯»æ—¥æœŸ '%1'" msgid "ERROR: Couldn't load ticket '%1': %2.\\n" msgstr "æ— æ³•åŠ è½½ç”³è¯·å• '%1':%2.\\n" -#: html/Work/Tickets/Update.html:46 +#: html/Work/Tickets/Update.html:47 msgid "Edit" msgstr "编辑" @@ -2078,7 +2142,7 @@ msgstr "编辑" msgid "Edit Conditions" msgstr "编辑å‰ç½®æ¡ä»¶" -#: html/Admin/Queues/CustomFields.html:44 +#: html/Admin/Queues/CustomFields.html:45 #. ($Queue->Name) msgid "Edit Custom Fields for %1" msgstr "编辑 %1 的自订å—段" @@ -2172,15 +2236,19 @@ msgstr "最高å¦åŽ†" msgid "EffectiveId" msgstr "有效编å·" -#: lib/RT/Ticket_Overlay.pm:2644 lib/RT/Ticket_Overlay.pm:2712 +#: lib/RT/Ticket_Overlay.pm:2673 lib/RT/Ticket_Overlay.pm:2751 msgid "Either base or target must be specified" msgstr "需è¦æŒ‡å®šèµ·å§‹ç”³è¯·å•æˆ–目的申请å•" -#: html/Admin/Users/Modify.html:52 html/Admin/Users/Prefs.html:45 html/Elements/SelectUsers:26 html/Ticket/Elements/AddWatchers:55 html/User/Prefs.html:41 html/Work/Delegates/Info:96 html/Work/Overview/Info:78 html/Work/Preferences/Info:16 +#: html/Admin/Users/Modify.html:52 html/Admin/Users/Prefs.html:45 html/Edit/Elements/SelectUsers:4 html/Edit/Users/List:7 html/Elements/SelectUsers:26 html/Ticket/Elements/AddWatchers:55 html/User/Prefs.html:43 html/Work/Delegates/Info:96 html/Work/Overview/Info:78 msgid "Email" msgstr "电å邮件信箱" -#: lib/RT/User_Overlay.pm:247 +#: html/Work/Preferences/Info:16 +msgid "Email Address" +msgstr "电å邮件信箱" + +#: lib/RT/User_Overlay.pm:251 msgid "Email address in use" msgstr "æ¤ç”µå邮件信箱已被使用" @@ -2220,11 +2288,11 @@ msgstr "å¯ç”¨(å–消勾选将åœç”¨æ¤ç¾¤ç»„)" msgid "Enabled (Unchecking this box disables this queue)" msgstr "å¯ç”¨(å–消勾选将åœç”¨æ¤è¡¨å•)" -#: html/Admin/Elements/EditCustomFields:98 +#: html/Admin/Elements/EditCustomFields:97 msgid "Enabled Custom Fields" msgstr "å·²å¯ç”¨çš„自订å—段" -#: html/Edit/Queues/Basic/Top:75 html/Edit/Queues/List:15 +#: html/Edit/Queues/Basic/Top:74 html/Edit/Queues/List:17 html/Edit/Queues/List:29 msgid "Enabled Date" msgstr "å¯ç”¨æ—¥æœŸ" @@ -2236,16 +2304,16 @@ msgstr "激活日期:" msgid "Enabled Queues" msgstr "å·²å¯ç”¨çš„表å•" -#: html/Edit/Queues/Basic/Top:66 html/Edit/Queues/List:11 +#: html/Edit/Queues/Basic/Top:65 html/Edit/Queues/List:13 html/Edit/Queues/List:25 msgid "Enabled Status" msgstr "å¯ç”¨çŠ¶æ€" -#: html/Admin/Elements/EditCustomField:106 html/Admin/Groups/Modify.html:116 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:282 html/User/Groups/Modify.html:116 +#: html/Admin/Elements/EditCustomField:106 html/Admin/Groups/Modify.html:116 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:284 html/User/Groups/Modify.html:116 #. (loc_fuzzy($msg)) msgid "Enabled status %1" msgstr "å¯ç”¨çŠ¶æ€ %1" -#: html/Edit/Users/Info:35 +#: NOT FOUND IN SOURCE msgid "End of Trial" msgstr "试用期满日" @@ -2265,7 +2333,7 @@ msgstr "输入下列å•ä¸€æˆ–å¤å¼æ¡ä»¶ï¼ŒæŸ¥è¯¢ç”¨æˆ·æ•°æ®" msgid "Enter one value" msgstr "键入å•ä¸€é¡¹ç›®" -#: html/Search/Bulk.html:144 html/Ticket/Elements/EditLinks:111 html/Work/Search/Bulk.html:95 +#: html/Search/Bulk.html:144 html/Ticket/Elements/EditLinks:94 html/Work/Search/Bulk.html:95 html/Work/Tickets/Elements/EditLinks:98 msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces." msgstr "输入申请å•å¯é“¾æŽ¥åˆ°çš„申请å•ç¼–å·æˆ–网å€ã€‚以空白隔开。" @@ -2317,15 +2385,15 @@ msgstr "表å•->新增视察员的å‚数有误" msgid "Error in parameters to Queue->DelWatcher" msgstr "表å•->åˆ é™¤è§†å¯Ÿå‘˜çš„å‚数有误" -#: lib/RT/Ticket_Overlay.pm:1364 +#: lib/RT/Ticket_Overlay.pm:1401 msgid "Error in parameters to Ticket->AddWatcher" msgstr "申请å•->新增视察员的å‚数有误" -#: lib/RT/Ticket_Overlay.pm:1540 +#: lib/RT/Ticket_Overlay.pm:1558 msgid "Error in parameters to Ticket->DelWatcher" msgstr "申请å•->åˆ é™¤è§†å¯Ÿå‘˜çš„å‚数有误" -#: etc/initialdata:38 +#: etc/initialdata:20 msgid "Everyone" msgstr "所有人" @@ -2333,7 +2401,11 @@ msgstr "所有人" msgid "Example:" msgstr "范例:" -#: html/Edit/Elements/104Buttons:77 +#: NOT FOUND IN SOURCE +msgid "Existing user renamed from %1 to %2" +msgstr "现有使用者 %1 已改å为 %2" + +#: html/Edit/Elements/104Buttons:88 msgid "Export" msgstr "汇出" @@ -2345,31 +2417,31 @@ msgstr "外部认è¯å¸å·" msgid "ExternalContactInfoId" msgstr "外部è”络方å¼å¸å·" -#: html/Edit/Global/Basic/Top:64 +#: html/Edit/Global/Basic/Top:69 msgid "ExternalDatabaseDSN" msgstr "外部数æ®åº“连结å—符串" -#: html/Edit/Global/Basic/Top:68 +#: html/Edit/Global/Basic/Top:73 msgid "ExternalDatabasePass" msgstr "外部数æ®åº“å£ä»¤" -#: html/Edit/Global/Basic/Top:66 +#: html/Edit/Global/Basic/Top:71 msgid "ExternalDatabaseUser" msgstr "外部数æ®åº“用户" -#: html/Edit/Global/Basic/Top:62 +#: html/Edit/Global/Basic/Top:67 msgid "ExternalURL" msgstr "外部接å£ç½‘å€" -#: html/Admin/Users/Modify.html:72 +#: html/Admin/Users/Modify.html:72 html/Edit/Users/Info:41 msgid "Extra info" msgstr "备注" -#: lib/RT/User_Overlay.pm:361 +#: lib/RT/User_Overlay.pm:368 msgid "Failed to find 'Privileged' users pseudogroup." msgstr "找ä¸åˆ°ã€Œå†…部æˆå‘˜ã€è™šæ‹Ÿç¾¤ç»„的使用者。" -#: lib/RT/User_Overlay.pm:368 +#: lib/RT/User_Overlay.pm:375 msgid "Failed to find 'Unprivileged' users pseudogroup" msgstr "找ä¸åˆ°ã€Œéžå†…部æˆå‘˜ã€è™šæ‹Ÿç¾¤ç»„的使用者。" @@ -2394,22 +2466,22 @@ msgstr "二月" msgid "Female" msgstr "女" -#: html/Edit/Global/CustomField/List:5 html/Edit/Global/CustomField/Top:9 -msgid "Field Attribute" -msgstr "å—段属性" - #: html/Edit/Global/CustomField/Info:14 msgid "Field Content:" msgstr "å—段内容:" -#: html/Edit/Global/CustomField/List:7 html/Edit/Global/CustomField/Top:21 +#: html/Edit/Global/CustomField/List:7 html/Edit/Global/CustomField/Top:20 msgid "Field Description" msgstr "å—段æè¿°" -#: html/Edit/Global/CustomField/List:6 html/Edit/Global/CustomField/Top:15 +#: html/Edit/Global/CustomField/List:6 html/Edit/Global/CustomField/Top:14 msgid "Field Name" msgstr "å—段å称" +#: html/Edit/Global/CustomField/List:5 html/Edit/Global/CustomField/Top:9 +msgid "Field Type" +msgstr "å—段属性" + #: html/Edit/Elements/PickUsers:52 html/Edit/Users/Add.html:47 msgid "Filter" msgstr "ç›é€‰" @@ -2426,19 +2498,19 @@ msgstr "ç›é€‰åˆ—表:" msgid "Fin" msgstr "最终" -#: html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:58 lib/RT/Tickets_Overlay.pm:1091 +#: html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:58 html/Work/Tickets/Elements/EditBasics:52 lib/RT/Tickets_Overlay.pm:1110 msgid "Final Priority" -msgstr "最低顺ä½" +msgstr "最终顺ä½" -#: lib/RT/Ticket_Overlay.pm:1170 +#: lib/RT/Ticket_Overlay.pm:1207 msgid "FinalPriority" -msgstr "最低顺ä½" +msgstr "最终顺ä½" #: NOT FOUND IN SOURCE msgid "Financial Department:" msgstr "财务部:" -#: html/Admin/Queues/People.html:60 html/Ticket/Elements/EditPeople:33 +#: html/Admin/Queues/People.html:60 html/Ticket/Elements/EditPeople:33 html/Work/Tickets/Elements/EditPeople:18 msgid "Find group whose" msgstr "寻找群组的" @@ -2446,10 +2518,14 @@ msgstr "寻找群组的" msgid "Find new/open tickets" msgstr "寻找/å¼€å¯ç”³è¯·å•" -#: html/Admin/Queues/People.html:56 html/Admin/Users/index.html:45 html/Ticket/Elements/EditPeople:29 +#: html/Admin/Queues/People.html:56 html/Admin/Users/index.html:45 html/Edit/Users/Top:6 html/Ticket/Elements/EditPeople:29 html/Work/Tickets/Elements/EditPeople:14 msgid "Find people whose" msgstr "寻找人员的" +#: html/Edit/Queues/Top:6 +msgid "Find queues whose" +msgstr "寻找表å•çš„" + #: html/Search/Listing.html:107 html/Work/Search/index.html:88 msgid "Find tickets" msgstr "寻找申请å•" @@ -2474,7 +2550,7 @@ msgstr "一" msgid "First-level Admins" msgstr "一阶主管" -#: html/Edit/Users/Info:40 +#: NOT FOUND IN SOURCE msgid "First-level Users" msgstr "一阶主管员工" @@ -2482,17 +2558,17 @@ msgstr "一阶主管员工" msgid "Fixed shift" msgstr "固定ç" -#: docs/design_docs/string-extraction-guide.txt:33 +#: docs/design_docs/string-extraction-guide.txt:33 lib/RT/StyleGuide.pod:746 msgid "Foo Bar Baz" msgstr "甲 ä¹™ 丙" -#: docs/design_docs/string-extraction-guide.txt:24 +#: docs/design_docs/string-extraction-guide.txt:24 lib/RT/StyleGuide.pod:737 msgid "Foo!" msgstr "甲ï¼" #: html/Search/Bulk.html:86 html/Work/Search/Bulk.html:55 msgid "Force change" -msgstr "强制更新" +msgstr "强制更æ¢" #: html/Work/Elements/104Header:89 msgid "Form Processing" @@ -2503,7 +2579,7 @@ msgstr "电å表å•ä½œä¸šåŒº" msgid "Found %quant(%1,ticket)" msgstr "找到 %1 å¼ ç”³è¯·å•" -#: lib/RT/Interface/Web.pm:904 +#: lib/RT/Interface/Web.pm:964 msgid "Found Object" msgstr "已找到对象" @@ -2559,7 +2635,7 @@ msgstr "å®Œæ•´æ ‡å¤´æ¡£" msgid "Gecos" msgstr "登入å¸å·" -#: html/Edit/Users/Info:26 +#: NOT FOUND IN SOURCE msgid "Gender" msgstr "性别" @@ -2567,7 +2643,7 @@ msgstr "性别" msgid "Getting the current user from a pgp sig\\n" msgstr "å–å¾—ç›®å‰ä½¿ç”¨è€…çš„ pgp ç¾ç« \\n" -#: lib/RT/Transaction_Overlay.pm:593 +#: lib/RT/Transaction_Overlay.pm:551 #. ($New->Name) msgid "Given to %1" msgstr "交予 %1" @@ -2577,6 +2653,10 @@ msgid "Global" msgstr "全域设定" #: NOT FOUND IN SOURCE +msgid "Global Approval" +msgstr "全域ç¾æ ¸" + +#: NOT FOUND IN SOURCE msgid "Global Keyword Selections" msgstr "全域关键è¯é€‰å–" @@ -2588,7 +2668,7 @@ msgstr "拥有全域æƒé™åˆ—表:" msgid "Global Scrips" msgstr "全域手ç»" -#: html/Edit/Elements/Tab:38 +#: html/Edit/Elements/Tab:40 msgid "Global Setup" msgstr "全域设定" @@ -2597,7 +2677,11 @@ msgstr "全域设定" msgid "Global template: %1" msgstr "全域模æ¿ï¼š%1" -#: html/Admin/Elements/EditCustomFields:74 html/Admin/Queues/People.html:58 html/Admin/Queues/People.html:62 html/Admin/Queues/index.html:43 html/Admin/Users/index.html:48 html/Ticket/Elements/EditPeople:31 html/Ticket/Elements/EditPeople:35 html/index.html:40 +#: NOT FOUND IN SOURCE +msgid "GlobalApproval" +msgstr "全域ç¾æ ¸" + +#: html/Admin/Elements/EditCustomFields:73 html/Admin/Queues/People.html:58 html/Admin/Queues/People.html:62 html/Admin/Queues/index.html:43 html/Admin/Users/index.html:48 html/Ticket/Elements/EditPeople:31 html/Ticket/Elements/EditPeople:35 html/Work/Tickets/Elements/EditPeople:16 html/Work/Tickets/Elements/EditPeople:20 html/index.html:40 msgid "Go!" msgstr "执行" @@ -2625,6 +2709,10 @@ msgstr "群组" msgid "Group %1 %2: %3" msgstr "群组 %1 %2:%3" +#: NOT FOUND IN SOURCE +msgid "Group Admin" +msgstr "群组管ç†å‘˜" + #: html/Edit/Global/GroupRight/List:5 html/Edit/Global/GroupRight/Top:20 html/Edit/Groups/List:7 msgid "Group Description" msgstr "群组æè¿°" @@ -2637,7 +2725,7 @@ msgstr "群组管ç†" msgid "Group Members" msgstr "群组æˆå‘˜" -#: html/Edit/Elements/PickUsers:28 html/Edit/Global/GroupRight/List:4 html/Edit/Global/GroupRight/Top:10 html/Edit/Groups/List:6 html/Edit/Groups/Top:7 html/Edit/Users/Add.html:29 html/Edit/Users/Group:10 html/Edit/Users/Search.html:43 html/Work/Delegates/Add.html:15 html/Work/Tickets/Cc:24 +#: html/Edit/Elements/PickUsers:28 html/Edit/Global/GroupRight/List:4 html/Edit/Global/GroupRight/Top:10 html/Edit/Groups/List:6 html/Edit/Groups/Top:7 html/Edit/Queues/Basic/Add.html:15 html/Edit/Users/Add.html:29 html/Edit/Users/Group:10 html/Edit/Users/Search.html:43 html/Work/Delegates/Add.html:15 html/Work/Tickets/Cc:24 msgid "Group Name" msgstr "群组å称" @@ -2645,7 +2733,7 @@ msgstr "群组å称" msgid "Group Name:" msgstr "群组å称:" -#: html/Admin/Elements/GroupTabs:44 html/Admin/Elements/QueueTabs:56 html/Admin/Elements/SystemTabs:43 html/Admin/Global/index.html:54 html/Edit/Global/autohandler:12 html/Edit/Queues/autohandler:23 html/Edit/Users/Group:11 html/Edit/Users/index.html:123 +#: html/Admin/Elements/GroupTabs:44 html/Admin/Elements/QueueTabs:56 html/Admin/Elements/SystemTabs:43 html/Admin/Global/index.html:54 html/Edit/Global/autohandler:12 html/Edit/Queues/autohandler:27 html/Edit/Users/Group:11 html/Edit/Users/index.html:96 msgid "Group Rights" msgstr "群组æƒé™" @@ -2653,7 +2741,7 @@ msgstr "群组æƒé™" msgid "Group Rights:" msgstr "拥有群组æƒé™åˆ—表:" -#: html/Edit/Elements/Tab:34 +#: html/Edit/Elements/Tab:36 msgid "Group Setup" msgstr "群组设定" @@ -2661,7 +2749,7 @@ msgstr "群组设定" msgid "Group Status" msgstr "群组状æ€" -#: lib/RT/Group_Overlay.pm:964 +#: lib/RT/Group_Overlay.pm:962 msgid "Group already has member" msgstr "群组内已有æ¤æˆå‘˜" @@ -2674,15 +2762,19 @@ msgstr "æ— æ³•æ–°å¢žç¾¤ç»„" msgid "Group could not be created: %1" msgstr "æ— æ³•æ–°å¢žç¾¤ç»„ï¼š%1" -#: lib/RT/Group_Overlay.pm:496 +#: lib/RT/Group_Overlay.pm:494 msgid "Group created" msgstr "群组新增完毕" -#: lib/RT/Group_Overlay.pm:1132 +#: NOT FOUND IN SOURCE +msgid "Group created: %1" +msgstr "群组 %1 新增完毕" + +#: lib/RT/Group_Overlay.pm:1134 msgid "Group has no such member" msgstr "群组没有这个æˆå‘˜" -#: lib/RT/Group_Overlay.pm:944 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1437 lib/RT/Ticket_Overlay.pm:1515 +#: lib/RT/Group_Overlay.pm:942 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1455 lib/RT/Ticket_Overlay.pm:1533 msgid "Group not found" msgstr "找ä¸åˆ°ç¾¤ç»„" @@ -2695,6 +2787,14 @@ msgid "Group not specified.\\n" msgstr "未指定群组。\\n" #: NOT FOUND IN SOURCE +msgid "Group redescribed from %1 to %2" +msgstr "群组æè¿° %1 已改为 %2" + +#: NOT FOUND IN SOURCE +msgid "Group renamed from %1 to %2" +msgstr "群组 %1 已改å为 %2" + +#: NOT FOUND IN SOURCE msgid "Group with Queue Rights" msgstr "拥有表å•æƒé™ç¾¤ç»„" @@ -2706,11 +2806,11 @@ msgstr "群组之" msgid "Group:" msgstr "群组:" -#: html/Admin/Elements/SelectNewGroupMembers:34 html/Admin/Elements/Tabs:34 html/Admin/Groups/Members.html:63 html/Admin/Queues/People.html:82 html/Admin/index.html:31 html/Edit/Global/GroupRight/Add.html:15 html/User/Groups/Members.html:66 +#: html/Admin/Elements/SelectNewGroupMembers:34 html/Admin/Elements/Tabs:34 html/Admin/Groups/Members.html:63 html/Admin/Queues/People.html:82 html/Admin/index.html:31 html/Edit/Global/GroupRight/Add.html:16 html/Edit/Groups/Admin:12 html/User/Groups/Members.html:66 msgid "Groups" msgstr "群组" -#: lib/RT/Group_Overlay.pm:970 +#: lib/RT/Group_Overlay.pm:968 msgid "Groups can't be members of their members" msgstr "ä¸èƒ½å°†ç¾¤ç»„设为群组内æˆå‘˜" @@ -2722,7 +2822,7 @@ msgstr "拥有全域æƒé™ç¾¤ç»„" msgid "HRMSDefined" msgstr "组织架构" -#: html/Edit/Users/Info:32 +#: NOT FOUND IN SOURCE msgid "Health Insurance" msgstr "å¥ä¿è¡¥åŠ©èº«ä»½" @@ -2730,19 +2830,23 @@ msgstr "å¥ä¿è¡¥åŠ©èº«ä»½" msgid "Hello!" msgstr "å—¨ï¼" -#: docs/design_docs/string-extraction-guide.txt:40 +#: docs/design_docs/string-extraction-guide.txt:40 lib/RT/StyleGuide.pod:753 #. ($name) msgid "Hello, %1" msgstr "嗨,%1" -#: html/Edit/Elements/104Top:27 +#: html/Edit/Elements/104Top:28 msgid "Help" -msgstr "辅助说明" +msgstr "说明" #: NOT FOUND IN SOURCE msgid "Help Desks" msgstr "å„项业务窗å£" +#: html/Edit/Global/CustomField/SelectWritable:9 html/Edit/Queues/Basic/Top:80 +msgid "Hidden" +msgstr "éšè—" + #: html/Ticket/Elements/ShowHistory:29 html/Ticket/Elements/Tabs:87 html/Work/Tickets/Elements/ShowHistory:8 msgid "History" msgstr "纪录" @@ -2751,7 +2855,7 @@ msgstr "纪录" msgid "HomePhone" msgstr "ä½å¤„电è¯" -#: html/Edit/Elements/104Top:15 html/Edit/Elements/104Top:23 html/Edit/Elements/EDOMHeader:9 html/Elements/Tabs:43 +#: html/Edit/Elements/104Top:15 html/Edit/Elements/104Top:24 html/Edit/Elements/EDOMHeader:9 html/Elements/Tabs:43 msgid "Homepage" msgstr "主页" @@ -2759,7 +2863,7 @@ msgstr "主页" msgid "Hotel Expense" msgstr "ä½å®¿è´¹" -#: lib/RT/Base.pm:73 +#: lib/RT/Base.pm:75 #. (6) msgid "I have %quant(%1,concrete mixer)." msgstr "我有 %quant(%1,份固体æ…拌器)。" @@ -2772,7 +2876,7 @@ msgstr "身分è¯å·" msgid "ID Type" msgstr "身分类别" -#: html/Ticket/Elements/ShowBasics:26 lib/RT/Tickets_Overlay.pm:1018 +#: html/Ticket/Elements/ShowBasics:26 lib/RT/Tickets_Overlay.pm:1037 msgid "Id" msgstr "ç¼–å·" @@ -2780,7 +2884,7 @@ msgstr "ç¼–å·" msgid "Identity" msgstr "身份" -#: etc/initialdata:439 etc/upgrade/2.1.71:86 html/Edit/Elements/CreateApprovalsQueue:58 +#: etc/initialdata:411 etc/upgrade/2.1.71:86 html/Edit/Elements/CreateApprovalsQueue:58 msgid "If an approval is rejected, reject the original and delete pending approvals" msgstr "è‹¥ç¾æ ¸å•é到驳回,则连带驳回原申请å•ï¼Œå¹¶åˆ 除其它相关的待ç¾æ ¸äº‹é¡¹" @@ -2792,43 +2896,43 @@ msgstr "如果æ¤å·¥å…·ç¨‹åºä¸º setgid,æ¶æ„的本地端用户å³èƒ½ç”±æ¤å msgid "If you've updated anything above, be sure to" msgstr "若您已更新以上数æ®ï¼Œè¯·è®°å¾—按一下" -#: lib/RT/Interface/Web.pm:896 +#: lib/RT/Interface/Web.pm:956 msgid "Illegal value for %1" msgstr "%1 的值错误" -#: lib/RT/Interface/Web.pm:899 +#: lib/RT/Interface/Web.pm:959 msgid "Immutable field" msgstr "æ¤å—段值ä¸å¯æ›´åŠ¨" -#: html/Edit/Elements/104Buttons:76 html/Edit/Global/Workflow/Import.html:2 +#: html/Edit/Elements/104Buttons:87 html/Edit/Global/Workflow/Import.html:2 msgid "Import" msgstr "汇入" -#: html/Admin/Elements/EditCustomFields:73 +#: html/Admin/Elements/EditCustomFields:72 msgid "Include disabled custom fields in listing." msgstr "列出åœç”¨çš„自订å—段" -#: html/Admin/Queues/index.html:42 html/Edit/Queues/index.html:38 +#: html/Admin/Queues/index.html:42 html/Edit/Queues/Top:9 msgid "Include disabled queues in listing." msgstr "列出åœç”¨çš„表å•" -#: html/Admin/Users/index.html:46 html/Edit/Users/Search.html:62 +#: html/Admin/Users/index.html:46 html/Edit/Users/Search.html:62 html/Edit/Users/Top:9 msgid "Include disabled users in search." msgstr "列出åœç”¨çš„使用者" -#: html/Edit/Users/Info:37 +#: NOT FOUND IN SOURCE msgid "Indirect Employee" msgstr "直接/间接员工" -#: lib/RT/Tickets_Overlay.pm:1067 +#: lib/RT/Tickets_Overlay.pm:1086 msgid "Initial Priority" -msgstr "åˆå§‹ä¼˜å…ˆæƒ" +msgstr "åˆå§‹ä¼˜å…ˆé¡ºä½" -#: lib/RT/Ticket_Overlay.pm:1169 lib/RT/Ticket_Overlay.pm:1171 +#: lib/RT/Ticket_Overlay.pm:1206 lib/RT/Ticket_Overlay.pm:1208 msgid "InitialPriority" -msgstr "åˆå§‹ä¼˜å…ˆæƒ" +msgstr "åˆå§‹ä¼˜å…ˆé¡ºä½" -#: lib/RT/ScripAction_Overlay.pm:104 +#: lib/RT/ScripAction_Overlay.pm:105 msgid "Input error" msgstr "输入错误" @@ -2836,7 +2940,7 @@ msgstr "输入错误" msgid "Interest noted" msgstr "登记æˆåŠŸ" -#: lib/RT/Ticket_Overlay.pm:3835 +#: lib/RT/Ticket_Overlay.pm:3913 msgid "Internal Error" msgstr "内部错误" @@ -2845,11 +2949,11 @@ msgstr "内部错误" msgid "Internal Error: %1" msgstr "内部错误:%1" -#: lib/RT/Group_Overlay.pm:643 +#: lib/RT/Group_Overlay.pm:641 msgid "Invalid Group Type" msgstr "错误的群组类别" -#: lib/RT/Principal_Overlay.pm:126 +#: lib/RT/Principal_Overlay.pm:127 msgid "Invalid Right" msgstr "错误的æƒé™" @@ -2857,15 +2961,15 @@ msgstr "错误的æƒé™" msgid "Invalid Type" msgstr "错误的类型" -#: lib/RT/Interface/Web.pm:901 +#: lib/RT/Interface/Web.pm:961 msgid "Invalid data" msgstr "错误的数æ®" -#: lib/RT/Ticket_Overlay.pm:439 +#: lib/RT/Ticket_Overlay.pm:463 msgid "Invalid owner. Defaulting to 'nobody'." msgstr "错误的承办人。改为预设承办人「nobodyã€ã€‚" -#: lib/RT/Scrip_Overlay.pm:133 lib/RT/Template_Overlay.pm:250 +#: lib/RT/Scrip_Overlay.pm:133 lib/RT/Template_Overlay.pm:251 msgid "Invalid queue" msgstr "错误的表å•" @@ -2878,11 +2982,11 @@ msgstr "错误的æƒé™" msgid "Invalid value for %1" msgstr "%1 的值错误" -#: lib/RT/Ticket_Overlay.pm:3470 +#: lib/RT/Ticket_Overlay.pm:3517 msgid "Invalid value for custom field" msgstr "错误的自订å—段值" -#: lib/RT/Ticket_Overlay.pm:346 +#: lib/RT/Ticket_Overlay.pm:365 msgid "Invalid value for status" msgstr "错误的状æ€å€¼" @@ -2940,7 +3044,7 @@ msgstr "七月" #: lib/RT/Date.pm:417 msgid "Jul." -msgstr "01" +msgstr "07" #: NOT FOUND IN SOURCE msgid "July" @@ -2956,7 +3060,7 @@ msgstr "å…月" #: lib/RT/Date.pm:416 msgid "Jun." -msgstr "06." +msgstr "06" #: NOT FOUND IN SOURCE msgid "June" @@ -2966,6 +3070,18 @@ msgstr "å…月" msgid "Keyword" msgstr "关键è¯" +#: lib/RT/CustomField_Vendor.pm:23 +msgid "LabelAttachments" +msgstr "附件å·æ ‡" + +#: lib/RT/CustomField_Vendor.pm:24 +msgid "LabelContent" +msgstr "内容å·æ ‡" + +#: lib/RT/CustomField_Vendor.pm:22 +msgid "LabelSubject" +msgstr "主题å·æ ‡" + #: lib/RT/CustomField_Vendor.pm:21 msgid "LabelURL" msgstr "链接å·æ ‡" @@ -2974,11 +3090,15 @@ msgstr "链接å·æ ‡" msgid "Lang" msgstr "使用è¯è¨€" +#: html/User/Prefs.html:54 html/Work/Preferences/Info:29 +msgid "Language" +msgstr "è¯è¨€" + #: html/Ticket/Elements/Tabs:72 msgid "Last" msgstr "上次更新" -#: html/Ticket/Elements/EditDates:37 html/Ticket/Elements/ShowDates:38 +#: html/Ticket/Elements/EditDates:37 html/Ticket/Elements/ShowDates:39 html/Work/Tickets/Elements/EditBasics:44 msgid "Last Contact" msgstr "上次è”络" @@ -3002,11 +3122,11 @@ msgstr "上次更新" msgid "Left" msgstr "剩馀时间" -#: html/Admin/Users/Modify.html:82 +#: html/Admin/Users/Modify.html:82 html/Edit/Users/Info:62 msgid "Let this user access RT" msgstr "å…许这å使用者登入" -#: html/Admin/Users/Modify.html:86 +#: html/Admin/Users/Modify.html:86 html/Edit/Users/Info:68 msgid "Let this user be granted rights" msgstr "内部æˆå‘˜ï¼ˆå…·æœ‰ä¸ªäººæƒé™ï¼‰" @@ -3022,25 +3142,25 @@ msgstr "é™åˆ¶è¡¨å•ä¸º %1 到 %2" msgid "Link a Queue" msgstr "申请表å•è¿žç»“" -#: lib/RT/Ticket_Overlay.pm:2726 +#: lib/RT/Ticket_Overlay.pm:2765 msgid "Link already exists" msgstr "æ¤é“¾æŽ¥å·²å˜åœ¨" -#: lib/RT/Ticket_Overlay.pm:2738 +#: lib/RT/Ticket_Overlay.pm:2777 msgid "Link could not be created" msgstr "æ— æ³•æ–°å¢žé“¾æŽ¥" -#: lib/RT/Ticket_Overlay.pm:2746 lib/RT/Ticket_Overlay.pm:2756 +#: lib/RT/Ticket_Overlay.pm:2785 lib/RT/Ticket_Overlay.pm:2797 #. ($TransString) msgid "Link created (%1)" msgstr "链接(%1)新增完毕" -#: lib/RT/Ticket_Overlay.pm:2667 +#: lib/RT/Ticket_Overlay.pm:2698 #. ($TransString) msgid "Link deleted (%1)" msgstr "链接(%1)åˆ é™¤å®Œæ¯•" -#: lib/RT/Ticket_Overlay.pm:2673 +#: lib/RT/Ticket_Overlay.pm:2704 msgid "Link not found" msgstr "找ä¸åˆ°é“¾æŽ¥" @@ -3061,33 +3181,33 @@ msgstr "链接" msgid "List All Users" msgstr "列出所有用户数æ®" -#: html/Admin/Users/Modify.html:113 html/User/Prefs.html:84 html/Work/Preferences/Info:72 +#: html/Admin/Users/Modify.html:113 html/User/Prefs.html:107 html/Work/Preferences/Info:75 msgid "Location" msgstr "ä½ç½®" -#: lib/RT.pm:162 +#: lib/RT.pm:174 #. ($RT::LogDir) msgid "Log directory %1 not found or couldn't be written.\\n RT can't run." msgstr "登入目录 %1 找ä¸åˆ°æˆ–æ— æ³•å†™å…¥\\nã€‚æ— æ³•æ‰§è¡Œ RT。" -#: html/Edit/Global/Basic/Top:52 +#: html/Edit/Global/Basic/Top:57 msgid "LogToFile" msgstr "纪录ç‰çº§" -#: html/Edit/Global/Basic/Top:54 +#: html/Edit/Global/Basic/Top:59 msgid "LogToFileNamed" msgstr "纪录档å" -#: html/Elements/Header:56 +#: html/Elements/Header:57 #. ("<b>".$session{'CurrentUser'}->Name."</b>") msgid "Logged in as %1" msgstr "使用者:%1" -#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54 +#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54 lib/RT/StyleGuide.pod:777 msgid "Login" msgstr "登入" -#: html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:29 html/Elements/Header:53 +#: html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:32 html/Elements/Header:54 msgid "Logout" msgstr "注销" @@ -3175,6 +3295,10 @@ msgstr "三月" msgid "Marketing Department" msgstr "行销部" +#: html/Edit/Global/CustomField/Top:63 +msgid "Match Pattern" +msgstr "符åˆæ ·å¼" + #: NOT FOUND IN SOURCE msgid "May" msgstr "五月" @@ -3183,23 +3307,33 @@ msgstr "五月" msgid "May." msgstr "05" -#: lib/RT/Group_Overlay.pm:981 +#: lib/RT/Transaction_Overlay.pm:598 +#. ($value) +msgid "Member %1 added" +msgstr "æˆå‘˜ %1 新增完毕" + +#: lib/RT/Transaction_Overlay.pm:635 +#. ($value) +msgid "Member %1 deleted" +msgstr "æˆå‘˜ %1 åˆ é™¤å®Œæ¯•" + +#: lib/RT/Group_Overlay.pm:979 msgid "Member added" msgstr "新增æˆå‘˜å®Œæ¯•" -#: lib/RT/Group_Overlay.pm:1139 +#: lib/RT/Group_Overlay.pm:1141 msgid "Member deleted" msgstr "æˆå‘˜å·²åˆ 除" -#: lib/RT/Group_Overlay.pm:1143 +#: lib/RT/Group_Overlay.pm:1145 msgid "Member not deleted" -msgstr "æˆå‘˜æœªè¢«åˆ 除" +msgstr "æˆå‘˜æœªåˆ 除" #: html/Elements/SelectLinkType:25 msgid "Member of" msgstr "隶属于" -#: html/Work/Preferences/index.html:20 +#: html/Work/Preferences/index.html:19 msgid "Member since" msgstr "注册日期" @@ -3211,15 +3345,25 @@ msgstr "隶属于" msgid "Members" msgstr "æˆå‘˜" -#: lib/RT/Ticket_Overlay.pm:2913 +#: lib/RT/Transaction_Overlay.pm:595 +#. ($value) +msgid "Membership in %1 added" +msgstr "所属群组 %1 åŠ å…¥å®Œæ¯•" + +#: lib/RT/Transaction_Overlay.pm:632 +#. ($value) +msgid "Membership in %1 deleted" +msgstr "所属群组 %1 移除完毕" + +#: lib/RT/Ticket_Overlay.pm:2954 msgid "Merge Successful" msgstr "æ•´åˆå®Œæ¯•" -#: lib/RT/Ticket_Overlay.pm:2833 +#: lib/RT/Ticket_Overlay.pm:2874 msgid "Merge failed. Couldn't set EffectiveId" msgstr "æ•´åˆå¤±è´¥ã€‚æ— æ³•è®¾å®š EffectiveId" -#: html/Ticket/Elements/BulkLinks:26 html/Ticket/Elements/EditLinks:114 html/Work/Search/BulkLinks:2 +#: html/Ticket/Elements/BulkLinks:26 html/Ticket/Elements/EditLinks:97 html/Work/Search/BulkLinks:2 html/Work/Tickets/Elements/EditLinks:101 msgid "Merge into" msgstr "æ•´åˆè¿›" @@ -3227,15 +3371,19 @@ msgstr "æ•´åˆè¿›" msgid "Message" msgstr "讯æ¯" +#: html/Ticket/Elements/ShowTransaction:80 +msgid "Message body not shown because it is too large or is not plain text." +msgstr "信件内文ä¸æ˜¯çº¯æ–‡å—ï¼Œå› æ¤æ— 法显示。" + #: NOT FOUND IN SOURCE msgid "Misc. Expense" msgstr "æ‚è´¹" -#: lib/RT/Interface/Web.pm:903 +#: lib/RT/Interface/Web.pm:963 msgid "Missing a primary key?: %1" msgstr "缺少主键值?(%1)" -#: html/Admin/Users/Modify.html:168 html/User/Prefs.html:53 html/Work/Preferences/Info:33 +#: html/Admin/Users/Modify.html:168 html/User/Prefs.html:71 html/Work/Preferences/Info:38 msgid "Mobile" msgstr "行动电è¯" @@ -3392,7 +3540,7 @@ msgstr "更改群组 %1" msgid "Modify the queue watchers" msgstr "更改表å•è§†å¯Ÿå‘˜" -#: html/Admin/Users/Modify.html:235 +#: html/Admin/Users/Modify.html:237 #. ($UserObj->Name) msgid "Modify the user %1" msgstr "更改使用者 %1" @@ -3471,6 +3619,10 @@ msgstr "星期一" msgid "Mon." msgstr "星期一" +#: html/Work/Elements/MyRequests:11 html/Work/Elements/MyTickets:11 +msgid "More" +msgstr "更多" + #: html/Ticket/Elements/ShowRequestor:41 #. ($name) msgid "More about %1" @@ -3496,7 +3648,7 @@ msgstr "上移" msgid "Multiple" msgstr "多é‡" -#: lib/RT/User_Overlay.pm:238 +#: lib/RT/User_Overlay.pm:242 msgid "Must specify 'Name' attribute" msgstr "必须指定 'Name' 的属性" @@ -3505,15 +3657,15 @@ msgstr "必须指定 'Name' 的属性" msgid "My %1 tickets" msgstr "我的 %1 申请å•" -#: html/Work/Elements/Tab:35 +#: html/Work/Elements/Tab:37 msgid "My Approvals" msgstr "表å•ç¾æ ¸" -#: html/Work/Elements/Tab:33 +#: html/Work/Elements/Tab:35 msgid "My Requests" msgstr "表å•ç”³è¯·è¿½è¸ª" -#: html/Work/Elements/Tab:37 +#: html/Work/Elements/Tab:39 msgid "My Tickets" msgstr "表å•å¤„ç†" @@ -3521,15 +3673,15 @@ msgstr "表å•å¤„ç†" msgid "My approvals" msgstr "表å•ç¾æ ¸" -#: html/Admin/Elements/AddCustomFieldValue:31 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/ModifyTemplate:27 html/Admin/Elements/ModifyTemplateAsWorkflow:185 html/Admin/Elements/ModifyUser:29 html/Admin/Groups/Modify.html:43 html/Edit/Users/Add.html:22 html/Edit/Users/Search.html:31 html/Elements/SelectGroups:25 html/Elements/SelectUsers:27 html/User/Groups/Modify.html:43 html/Work/Tickets/Cc:18 +#: html/Admin/Elements/AddCustomFieldValue:31 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/ModifyTemplate:27 html/Admin/Elements/ModifyTemplateAsWorkflow:185 html/Admin/Elements/ModifyUser:29 html/Admin/Groups/Modify.html:43 html/Edit/Elements/SelectQueues:3 html/Edit/Queues/List:8 html/Edit/Users/Add.html:22 html/Edit/Users/List:5 html/Edit/Users/Search.html:31 html/Elements/SelectGroups:25 html/Elements/SelectUsers:27 html/User/Groups/Modify.html:43 html/Work/Tickets/Cc:18 msgid "Name" msgstr "å称" -#: lib/RT/User_Overlay.pm:245 +#: lib/RT/User_Overlay.pm:249 msgid "Name in use" msgstr "å¸å·å·²æœ‰äººä½¿ç”¨" -#: html/Edit/Users/Info:27 +#: NOT FOUND IN SOURCE msgid "Nationality" msgstr "国ç±" @@ -3537,27 +3689,27 @@ msgstr "国ç±" msgid "Need approval from system administrator" msgstr "需先由系统管ç†å‘˜è¿›è¡Œæ‰¹å‡†" -#: html/Ticket/Elements/ShowDates:51 +#: html/Ticket/Elements/ShowDates:52 msgid "Never" msgstr "从未更动" -#: html/Elements/Quicksearch:29 html/Work/Elements/Quicksearch:15 html/Work/Tickets/Create.html:52 +#: html/Elements/Quicksearch:29 html/Work/Elements/Quicksearch:15 html/Work/Tickets/Create.html:53 msgid "New" msgstr "新建立" -#: html/Admin/Elements/ModifyUser:31 html/Admin/Users/Modify.html:92 html/User/Prefs.html:64 html/Work/Preferences/Info:44 +#: html/Admin/Elements/ModifyUser:31 html/Admin/Users/Modify.html:92 html/Edit/Users/Info:33 html/User/Prefs.html:87 html/Work/Preferences/Info:49 msgid "New Password" msgstr "æ–°çš„å£ä»¤" -#: etc/initialdata:341 etc/upgrade/2.1.71:16 html/Edit/Elements/CreateApprovalsQueue:21 +#: etc/initialdata:317 etc/upgrade/2.1.71:16 html/Edit/Elements/CreateApprovalsQueue:21 msgid "New Pending Approval" msgstr "æ–°çš„å¾…ç¾æ ¸äº‹é¡¹" -#: html/Ticket/Elements/EditLinks:110 +#: html/Ticket/Elements/EditLinks:93 html/Work/Tickets/Elements/EditLinks:12 msgid "New Relationships" msgstr "新增关系" -#: html/Work/Elements/Tab:31 +#: html/Work/Elements/Tab:33 msgid "New Request" msgstr "表å•ç”³è¯·" @@ -3565,7 +3717,11 @@ msgstr "表å•ç”³è¯·" msgid "New Search" msgstr "新增查询" -#: html/Admin/Global/CustomField.html:40 html/Admin/Global/CustomFields.html:38 html/Admin/Queues/CustomField.html:51 html/Admin/Queues/CustomFields.html:39 +#: html/Work/Tickets/Elements/EditPeople:7 +msgid "New Watchers" +msgstr "新增视察员" + +#: html/Admin/Global/CustomField.html:40 html/Admin/Global/CustomFields.html:38 html/Admin/Queues/CustomField.html:51 html/Admin/Queues/CustomFields.html:40 msgid "New custom field" msgstr "新增自订å—段" @@ -3577,7 +3733,7 @@ msgstr "新增群组" msgid "New password" msgstr "æ–°çš„å£ä»¤" -#: lib/RT/User_Overlay.pm:706 +#: lib/RT/User_Overlay.pm:769 msgid "New password notification sent" msgstr "é€å‡ºæ–°å£ä»¤é€šçŸ¥" @@ -3609,7 +3765,7 @@ msgstr "新增模æ¿" msgid "New ticket" msgstr "æ出申请å•" -#: lib/RT/Ticket_Overlay.pm:2800 +#: lib/RT/Ticket_Overlay.pm:2841 msgid "New ticket doesn't exist" msgstr "没有新申请å•" @@ -3645,7 +3801,7 @@ msgstr "下一页" msgid "NickName" msgstr "昵称" -#: html/Admin/Users/Modify.html:62 html/User/Prefs.html:45 html/Work/Preferences/Info:23 +#: html/Admin/Users/Modify.html:62 html/User/Prefs.html:50 html/Work/Preferences/Info:26 msgid "Nickname" msgstr "昵称" @@ -3653,11 +3809,11 @@ msgstr "昵称" msgid "Night Shift" msgstr "å°å¤œç" -#: html/Edit/Global/Basic/Top:27 +#: html/Edit/Global/Basic/Top:27 html/Edit/Queues/Basic/Top:83 msgid "No" msgstr "å¦" -#: html/Admin/Elements/EditCustomField:89 html/Admin/Elements/EditCustomFields:104 +#: html/Admin/Elements/EditCustomField:89 html/Admin/Elements/EditCustomFields:103 msgid "No CustomField" msgstr "æ— è‡ªè®¢å—段" @@ -3693,7 +3849,7 @@ msgstr "没有æµç¨‹" msgid "No action" msgstr "æš‚ä¸å¤„ç†" -#: lib/RT/Interface/Web.pm:898 +#: lib/RT/Interface/Web.pm:958 msgid "No column specified" msgstr "未指定å—段" @@ -3705,7 +3861,7 @@ msgstr "找ä¸åˆ°å‘½ä»¤" msgid "No comment entered about this user" msgstr "没有对这å使用者的评论" -#: lib/RT/Ticket_Overlay.pm:2211 lib/RT/Ticket_Overlay.pm:2279 +#: lib/RT/Ticket_Overlay.pm:2229 lib/RT/Ticket_Overlay.pm:2299 msgid "No correspondence attached" msgstr "没有附上申请å•å›žå¤" @@ -3714,11 +3870,11 @@ msgstr "没有附上申请å•å›žå¤" msgid "No description for %1" msgstr "没有对 %1 çš„æè¿°" -#: lib/RT/Users_Overlay.pm:150 +#: lib/RT/Users_Overlay.pm:149 msgid "No group specified" msgstr "未指定群组" -#: lib/RT/User_Overlay.pm:924 +#: lib/RT/User_Overlay.pm:987 msgid "No password set" msgstr "没有设定å£ä»¤" @@ -3726,24 +3882,24 @@ msgstr "没有设定å£ä»¤" msgid "No permission to create queues" msgstr "没有新增表å•çš„æƒé™" -#: lib/RT/Ticket_Overlay.pm:342 +#: lib/RT/Ticket_Overlay.pm:361 #. ($QueueObj->Name) msgid "No permission to create tickets in the queue '%1'" msgstr "æ²¡æœ‰åœ¨è¡¨å• '%1' 新增申请å•çš„æƒé™" -#: lib/RT/User_Overlay.pm:211 +#: lib/RT/User_Overlay.pm:208 msgid "No permission to create users" msgstr "没有新增使用者的æƒé™" -#: html/SelfService/Display.html:117 +#: html/SelfService/Display.html:123 msgid "No permission to display that ticket" msgstr "没有显示该申请å•çš„æƒé™" -#: html/SelfService/Update.html:51 +#: html/SelfService/Update.html:68 msgid "No permission to view update ticket" msgstr "没有检视申请å•æ›´æ–°çš„æƒé™" -#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1496 +#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1514 msgid "No principal specified" msgstr "未指定å•ä½" @@ -3759,7 +3915,7 @@ msgstr "%1 内未指定åè®®" msgid "No queues matching search criteria found." msgstr "找ä¸åˆ°ç¬¦åˆæŸ¥è¯¢æ¡ä»¶çš„表å•ã€‚" -#: html/Admin/Elements/SelectRights:80 +#: html/Admin/Elements/SelectRights:81 msgid "No rights found" msgstr "找ä¸åˆ°æƒé™" @@ -3775,7 +3931,7 @@ msgstr "没有è¦è¿›è¡Œçš„查询" msgid "No ticket id specified" msgstr "未指定申请å•ç¼–å·" -#: lib/RT/Transaction_Overlay.pm:478 lib/RT/Transaction_Overlay.pm:516 +#: lib/RT/Transaction_Overlay.pm:427 lib/RT/Transaction_Overlay.pm:465 msgid "No transaction type specified" msgstr "未指定更动报告类别" @@ -3791,7 +3947,7 @@ msgstr "找ä¸åˆ°ç¬¦åˆæŸ¥è¯¢æ¡ä»¶çš„使用者。" msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n" msgstr "找ä¸åˆ°åˆæ ¼çš„ RT 使用者。RT cvs 处ç†å™¨å·²åœç”¨ã€‚è¯·å‘ RT 管ç†è€…询问。\\n" -#: lib/RT/Interface/Web.pm:895 +#: lib/RT/Interface/Web.pm:955 msgid "No value sent to _Set!\\n" msgstr "_Set 没有收到任何值!\\n" @@ -3799,7 +3955,7 @@ msgstr "_Set 没有收到任何值!\\n" msgid "Nobody" msgstr "没有人" -#: lib/RT/Interface/Web.pm:900 +#: lib/RT/Interface/Web.pm:960 msgid "Nonexistant field?" msgstr "å—段ä¸å˜åœ¨ï¼Ÿ" @@ -3815,7 +3971,7 @@ msgstr "未设定æˆä»Ž %2 å†…æ’·å– %1" msgid "Not logged in" msgstr "尚未登入" -#: html/Elements/Header:58 +#: html/Elements/Header:59 msgid "Not logged in." msgstr "尚未登入" @@ -3831,7 +3987,7 @@ msgstr "尚未完工。" msgid "Not yet implemented...." msgstr "尚未完工..." -#: html/Approvals/Elements/Approve:48 html/Work/Tickets/Create.html:134 +#: html/Approvals/Elements/Approve:48 html/Work/Tickets/Elements/AddContent:9 msgid "Notes" msgstr "备注" @@ -3839,67 +3995,67 @@ msgstr "备注" msgid "Notes:" msgstr "备注:" -#: lib/RT/User_Overlay.pm:709 +#: lib/RT/User_Overlay.pm:772 msgid "Notification could not be sent" msgstr "æ— æ³•é€å‡ºé€šçŸ¥" -#: etc/initialdata:111 +#: etc/initialdata:93 msgid "Notify AdminCcs" msgstr "通知管ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:107 +#: etc/initialdata:89 msgid "Notify AdminCcs as Comment" msgstr "以评论方å¼é€šçŸ¥ç®¡ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:138 +#: etc/initialdata:120 msgid "Notify Other Recipients" msgstr "通知其它收件人" -#: etc/initialdata:134 +#: etc/initialdata:116 msgid "Notify Other Recipients as Comment" msgstr "以评论方å¼é€šçŸ¥å…¶å®ƒæ”¶ä»¶äºº" -#: etc/initialdata:103 +#: etc/initialdata:85 msgid "Notify Owner" msgstr "通知承办人" -#: etc/initialdata:99 +#: etc/initialdata:81 msgid "Notify Owner as Comment" msgstr "以评论方å¼é€šçŸ¥æ‰¿åŠžäºº" -#: etc/initialdata:385 +#: etc/initialdata:361 msgid "Notify Owner of their rejected ticket" msgstr "通知承办人申请å•å·²é©³å›ž" -#: etc/initialdata:374 +#: etc/initialdata:350 msgid "Notify Owner of their ticket has been approved by all approvers" msgstr "通知承办人申请å•å·²å®Œæˆå…¨éƒ¨ç¾æ ¸" -#: etc/initialdata:359 +#: etc/initialdata:338 msgid "Notify Owner of their ticket has been approved by some approver" msgstr "通知承办人申请å•å·²å®ŒæˆæŸé¡¹ç¾æ ¸" -#: etc/initialdata:343 etc/upgrade/2.1.71:17 html/Edit/Elements/CreateApprovalsQueue:22 +#: etc/initialdata:319 etc/upgrade/2.1.71:17 html/Edit/Elements/CreateApprovalsQueue:22 msgid "Notify Owners and AdminCcs of new items pending their approval" msgstr "æ•´ç†å¾…ç¾æ ¸äº‹é¡¹ï¼Œé€šçŸ¥æ‰¿åŠžäººåŠç®¡ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:95 +#: etc/initialdata:77 msgid "Notify Requestors" msgstr "通知申请人" -#: etc/initialdata:121 +#: etc/initialdata:103 msgid "Notify Requestors and Ccs" msgstr "通知申请人åŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:116 +#: etc/initialdata:98 msgid "Notify Requestors and Ccs as Comment" msgstr "以评论方å¼é€šçŸ¥ç”³è¯·äººåŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:130 +#: etc/initialdata:112 msgid "Notify Requestors, Ccs and AdminCcs" msgstr "通知申请人ã€å‰¯æœ¬åŠç®¡ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:126 +#: etc/initialdata:108 msgid "Notify Requestors, Ccs and AdminCcs as Comment" msgstr "以评论方å¼é€šçŸ¥ç”³è¯·äººã€å‰¯æœ¬åŠç®¡ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" @@ -3919,9 +4075,9 @@ msgstr "11" msgid "November" msgstr "å一月" -#: html/Edit/Global/Basic/Top:74 +#: html/Edit/Global/Basic/Top:83 msgid "OIN104" -msgstr "é…åˆ 104eHRMS 接å£" +msgstr "104eHRMS 接å£" #: html/Edit/Global/Workflow/Export.html:30 html/Work/Copyright.html:23 msgid "OK" @@ -3935,7 +4091,7 @@ msgstr "æ— æ³•æ–°å¢žå¯¹è±¡" msgid "Object created" msgstr "对象新增完毕" -#: html/Edit/Users/Info:36 +#: NOT FOUND IN SOURCE msgid "Occupation Status" msgstr "在èŒçŠ¶æ€" @@ -3951,7 +4107,7 @@ msgstr "10" msgid "October" msgstr "å月" -#: html/Edit/Users/Info:33 +#: NOT FOUND IN SOURCE msgid "Office Phone" msgstr "办公室电è¯" @@ -3959,35 +4115,39 @@ msgstr "办公室电è¯" msgid "On" msgstr "ç‰äºŽ" -#: etc/initialdata:173 +#: html/Edit/Global/CustomField/Top:68 +msgid "On Change" +msgstr "更改申请å•æ—¶" + +#: etc/initialdata:155 msgid "On Comment" msgstr "评论时" -#: etc/initialdata:166 +#: etc/initialdata:148 msgid "On Correspond" msgstr "回å¤ç”³è¯·å•æ—¶" -#: etc/initialdata:155 +#: etc/initialdata:137 html/Edit/Global/CustomField/Top:57 msgid "On Create" msgstr "新增申请å•æ—¶" -#: etc/initialdata:187 +#: etc/initialdata:169 msgid "On Owner Change" msgstr "承办人改å˜æ—¶" -#: etc/initialdata:195 +#: etc/initialdata:177 msgid "On Queue Change" msgstr "表å•æ”¹å˜æ—¶" -#: etc/initialdata:201 +#: etc/initialdata:183 msgid "On Resolve" msgstr "解决申请å•æ—¶" -#: etc/initialdata:179 +#: etc/initialdata:161 msgid "On Status Change" msgstr "现况改å˜æ—¶" -#: etc/initialdata:160 +#: etc/initialdata:142 msgid "On Transaction" msgstr "å‘生更动时" @@ -4001,7 +4161,7 @@ msgstr "仅显示 %1 之åŽæ–°å¢žçš„申请å•" msgid "Only show approvals for requests created before %1" msgstr "仅显示 %1 之å‰æ–°å¢žçš„申请å•" -#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:18 html/Edit/Queues/Basic/Top:69 html/Edit/Queues/List:13 html/Elements/Quicksearch:30 html/Work/Delegates/Info:48 html/Work/Delegates/Info:51 html/Work/Delegates/List:12 html/Work/Elements/Quicksearch:16 html/Work/Overview/Info:41 html/Work/Tickets/Display.html:28 +#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:18 html/Edit/Queues/Basic/Top:68 html/Edit/Queues/List:15 html/Edit/Queues/List:27 html/Elements/Quicksearch:30 html/Work/Delegates/Info:48 html/Work/Delegates/Info:51 html/Work/Delegates/List:12 html/Work/Elements/Quicksearch:16 html/Work/Overview/Info:41 html/Work/Tickets/Display.html:51 msgid "Open" msgstr "å¼€å¯" @@ -4021,7 +4181,7 @@ msgstr "在新窗å£å¼€å¯(列表的)申请å•" msgid "Open tickets (from listing) in another window" msgstr "在å¦ä¸€ä¸ªçª—å£å¼€å¯(列表的)申请å•" -#: etc/initialdata:150 +#: etc/initialdata:132 msgid "Open tickets on correspondence" msgstr "收到回å¤æ—¶å³å¼€å¯ç”³è¯·å•" @@ -4041,11 +4201,11 @@ msgstr "选项æè¿°" msgid "Option Name" msgstr "选项å称" -#: html/Search/Elements/PickRestriction:100 html/Work/Search/PickRestriction:81 +#: html/Search/Elements/PickRestriction:100 html/Work/Search/PickRestriction:87 msgid "Ordering and sorting" msgstr "顺åºä¸ŽæŽ’åºæ–¹å¼" -#: html/Admin/Elements/ModifyUser:45 html/Admin/Users/Modify.html:116 html/Edit/Global/Basic/Top:50 html/Elements/SelectUsers:28 html/User/Prefs.html:85 html/Work/Preferences/Info:74 +#: html/Admin/Elements/ModifyUser:45 html/Admin/Users/Modify.html:116 html/Edit/Elements/SelectUsers:7 html/Edit/Global/Basic/Top:55 html/Elements/SelectUsers:28 html/User/Prefs.html:110 html/Work/Preferences/Info:77 msgid "Organization" msgstr "组织å称" @@ -4058,11 +4218,11 @@ msgstr "组织:" msgid "Originating ticket: #%1" msgstr "原申请å•ï¼š#%1" -#: html/Edit/Elements/PickUsers:109 html/Edit/Users/Add.html:106 html/Work/Tickets/Cc:80 +#: html/Edit/Elements/PickUsers:111 html/Edit/Users/Add.html:106 html/Work/Tickets/Cc:80 msgid "Other comma-delimited email addresses" msgstr "其它e-mailå¸å· (ä»…e-mail通知;多笔å¸å·è¯·ç”¨é€—å·','区隔)" -#: html/Admin/Elements/ModifyQueue:54 html/Admin/Queues/Modify.html:68 html/Edit/Queues/Basic/Top:41 +#: html/Admin/Elements/ModifyQueue:54 html/Admin/Queues/Modify.html:68 html/Edit/Queues/Basic/Top:44 msgid "Over time, priority moves toward" msgstr "优先顺ä½éšæ—¶é—´å¢žåŠ 调整为" @@ -4074,12 +4234,12 @@ msgstr "以 %1 表å•çš„自订å—段å–代现有å—段" msgid "Override global rights" msgstr "å–代全域æƒé™" -#: html/Admin/Elements/CheckOverrideGlobalACL:34 +#: html/Admin/Elements/CheckOverrideGlobalACL:36 #. (loc_fuzzy($msg)) msgid "OverrideGlobalACL status %1" msgstr "å–代全域æƒé™ %1" -#: html/Work/Elements/Tab:29 +#: html/Work/Elements/Tab:31 msgid "Overview" msgstr "总览" @@ -4091,7 +4251,7 @@ msgstr "承办申请å•" msgid "OwnTicket" msgstr "承办申请å•" -#: etc/initialdata:56 html/Admin/Elements/ModifyTemplateAsWorkflow:141 html/Edit/Global/Workflow/Owner.html:19 html/Edit/Queues/Basic/Top:47 html/Edit/Queues/Basic/Top:58 html/Elements/MyRequests:31 html/SelfService/Elements/MyRequests:29 html/Ticket/Create.html:47 html/Ticket/Elements/EditPeople:42 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/ShowPeople:26 html/Ticket/Update.html:62 html/Work/Elements/MyRequests:13 html/Work/Elements/Quicksearch:18 html/Work/Tickets/Elements/ShowBasics:21 html/Work/Tickets/Update.html:27 lib/RT/ACE_Overlay.pm:85 lib/RT/Tickets_Overlay.pm:1244 +#: etc/initialdata:38 html/Admin/Elements/ModifyTemplateAsWorkflow:141 html/Edit/Global/Workflow/Owner.html:19 html/Edit/Queues/Basic/Top:51 html/Edit/Queues/Basic/Top:59 html/Elements/MyRequests:31 html/SelfService/Elements/MyRequests:29 html/Ticket/Create.html:47 html/Ticket/Elements/EditPeople:42 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/ShowPeople:26 html/Ticket/Update.html:62 html/Work/Elements/MyRequests:19 html/Work/Elements/Quicksearch:18 html/Work/Tickets/Elements/EditPeople:28 html/Work/Tickets/Elements/ShowBasics:21 html/Work/Tickets/Update.html:27 lib/RT/ACE_Overlay.pm:85 lib/RT/Tickets_Overlay.pm:1263 msgid "Owner" msgstr "承办人" @@ -4099,7 +4259,7 @@ msgstr "承办人" msgid "Owner changed from %1 to %2" msgstr "承办人已从 %1 改为 %2" -#: lib/RT/Transaction_Overlay.pm:582 +#: lib/RT/Transaction_Overlay.pm:539 #. ($Old->Name , $New->Name) msgid "Owner forcibly changed from %1 to %2" msgstr "强制将承办人从 %1 改为 %2" @@ -4108,15 +4268,15 @@ msgstr "强制将承办人从 %1 改为 %2" msgid "Owner is" msgstr "承办人" -#: html/Work/Elements/List:27 html/Work/Queues/List:8 html/Work/Tickets/Create.html:54 html/Work/Tickets/Elements/ShowBasics:52 +#: html/Work/Elements/List:27 html/Work/Queues/List:8 html/Work/Tickets/Create.html:55 html/Work/Tickets/Elements/ShowBasics:60 msgid "Owner's Phone" msgstr "承办人电è¯" -#: html/Edit/Elements/Page:39 -msgid "Page" +#: html/Edit/Elements/Page:40 +msgid "Page #" msgstr " " -#: html/Admin/Users/Modify.html:173 html/User/Prefs.html:55 html/Work/Preferences/Info:35 +#: html/Admin/Users/Modify.html:173 html/User/Prefs.html:75 html/Work/Preferences/Info:40 msgid "Pager" msgstr "呼å«å™¨" @@ -4124,7 +4284,7 @@ msgstr "呼å«å™¨" msgid "PagerPhone" msgstr "呼å«å™¨å·ç " -#: html/Edit/Global/Workflow/Action:81 html/Edit/Global/Workflow/Condition:66 +#: html/Edit/Global/Workflow/Action:75 html/Edit/Global/Workflow/Condition:65 msgid "Parameter" msgstr "呼å«å‚æ•°" @@ -4132,7 +4292,7 @@ msgstr "呼å«å‚æ•°" msgid "Parent" msgstr "上级" -#: html/Ticket/Create.html:181 html/Ticket/Elements/BulkLinks:38 html/Ticket/Elements/EditLinks:126 html/Ticket/Elements/EditLinks:57 html/Ticket/Elements/ShowLinks:46 html/Work/Search/BulkLinks:14 +#: html/Ticket/Create.html:182 html/Ticket/Elements/BulkLinks:38 html/Ticket/Elements/EditLinks:109 html/Ticket/Elements/EditLinks:54 html/Ticket/Elements/ShowLinks:46 html/Work/Search/BulkLinks:14 html/Work/Tickets/Elements/EditLinks:113 html/Work/Tickets/Elements/EditLinks:45 html/Work/Tickets/Elements/ShowLinks:26 msgid "Parents" msgstr "æ¯ç”³è¯·å•" @@ -4140,7 +4300,7 @@ msgstr "æ¯ç”³è¯·å•" msgid "Park Space" msgstr "åœè½¦ä½ç”³è¯·" -#: html/Elements/Login:52 html/User/Prefs.html:60 html/Work/Preferences/Info:41 +#: html/Elements/Login:52 html/User/Prefs.html:83 html/Work/Preferences/Info:46 msgid "Password" msgstr "å£ä»¤" @@ -4148,20 +4308,20 @@ msgstr "å£ä»¤" msgid "Password Reminder" msgstr "å£ä»¤æ示" -#: lib/RT/User_Overlay.pm:228 lib/RT/User_Overlay.pm:927 +#: lib/RT/User_Overlay.pm:230 lib/RT/User_Overlay.pm:990 msgid "Password too short" msgstr "å£ä»¤å¤ªçŸ" -#: html/Admin/Users/Modify.html:290 html/User/Prefs.html:171 html/Work/Preferences/Info:162 +#: html/Admin/Users/Modify.html:292 html/User/Prefs.html:209 html/Work/Preferences/Info:173 #. (loc_fuzzy($msg)) msgid "Password: %1" msgstr "å£ä»¤ï¼š%1" -#: html/Admin/Users/Modify.html:292 +#: html/Admin/Users/Modify.html:294 msgid "Passwords do not match." msgstr "å£ä»¤ç¡®è®¤å¤±è´¥ã€‚" -#: html/User/Prefs.html:173 html/Work/Preferences/Info:164 +#: html/User/Prefs.html:211 html/Work/Preferences/Info:175 msgid "Passwords do not match. Your password has not been changed" msgstr "å£ä»¤ç¡®è®¤å¤±è´¥ã€‚您的å£ä»¤å¹¶æœªæ”¹å˜ã€‚" @@ -4181,11 +4341,11 @@ msgstr "人员" msgid "People with Queue Rights" msgstr "拥有表å•æƒé™äººå‘˜" -#: etc/initialdata:143 +#: etc/initialdata:125 msgid "Perform a user-defined action" msgstr "执行使用者自订的动作" -#: lib/RT/ACE_Overlay.pm:230 lib/RT/ACE_Overlay.pm:236 lib/RT/ACE_Overlay.pm:562 lib/RT/ACE_Overlay.pm:572 lib/RT/ACE_Overlay.pm:582 lib/RT/ACE_Overlay.pm:647 lib/RT/CurrentUser.pm:82 lib/RT/CurrentUser.pm:91 lib/RT/CustomField_Overlay.pm:100 lib/RT/CustomField_Overlay.pm:201 lib/RT/CustomField_Overlay.pm:233 lib/RT/CustomField_Overlay.pm:510 lib/RT/CustomField_Overlay.pm:90 lib/RT/Group_Overlay.pm:1094 lib/RT/Group_Overlay.pm:1098 lib/RT/Group_Overlay.pm:1107 lib/RT/Group_Overlay.pm:1158 lib/RT/Group_Overlay.pm:1162 lib/RT/Group_Overlay.pm:1168 lib/RT/Group_Overlay.pm:425 lib/RT/Group_Overlay.pm:517 lib/RT/Group_Overlay.pm:595 lib/RT/Group_Overlay.pm:603 lib/RT/Group_Overlay.pm:700 lib/RT/Group_Overlay.pm:704 lib/RT/Group_Overlay.pm:710 lib/RT/Group_Overlay.pm:903 lib/RT/Group_Overlay.pm:907 lib/RT/Group_Overlay.pm:920 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:125 lib/RT/Scrip_Overlay.pm:136 lib/RT/Scrip_Overlay.pm:196 lib/RT/Scrip_Overlay.pm:429 lib/RT/Template_Overlay.pm:283 lib/RT/Template_Overlay.pm:87 lib/RT/Template_Overlay.pm:93 lib/RT/Ticket_Overlay.pm:1349 lib/RT/Ticket_Overlay.pm:1359 lib/RT/Ticket_Overlay.pm:1373 lib/RT/Ticket_Overlay.pm:1526 lib/RT/Ticket_Overlay.pm:1535 lib/RT/Ticket_Overlay.pm:1548 lib/RT/Ticket_Overlay.pm:1897 lib/RT/Ticket_Overlay.pm:2035 lib/RT/Ticket_Overlay.pm:2199 lib/RT/Ticket_Overlay.pm:2266 lib/RT/Ticket_Overlay.pm:2625 lib/RT/Ticket_Overlay.pm:2697 lib/RT/Ticket_Overlay.pm:2791 lib/RT/Ticket_Overlay.pm:2806 lib/RT/Ticket_Overlay.pm:3005 lib/RT/Ticket_Overlay.pm:3015 lib/RT/Ticket_Overlay.pm:3020 lib/RT/Ticket_Overlay.pm:3242 lib/RT/Ticket_Overlay.pm:3440 lib/RT/Ticket_Overlay.pm:3602 lib/RT/Ticket_Overlay.pm:3654 lib/RT/Ticket_Overlay.pm:3829 lib/RT/Transaction_Overlay.pm:466 lib/RT/Transaction_Overlay.pm:473 lib/RT/Transaction_Overlay.pm:502 lib/RT/Transaction_Overlay.pm:509 lib/RT/User_Overlay.pm:1021 lib/RT/User_Overlay.pm:1414 lib/RT/User_Overlay.pm:629 lib/RT/User_Overlay.pm:664 lib/RT/User_Overlay.pm:920 +#: lib/RT/ACE_Overlay.pm:230 lib/RT/ACE_Overlay.pm:236 lib/RT/ACE_Overlay.pm:562 lib/RT/ACE_Overlay.pm:572 lib/RT/ACE_Overlay.pm:582 lib/RT/ACE_Overlay.pm:647 lib/RT/CurrentUser.pm:82 lib/RT/CurrentUser.pm:91 lib/RT/CustomField_Overlay.pm:100 lib/RT/CustomField_Overlay.pm:201 lib/RT/CustomField_Overlay.pm:233 lib/RT/CustomField_Overlay.pm:511 lib/RT/CustomField_Overlay.pm:90 lib/RT/Group_Overlay.pm:1096 lib/RT/Group_Overlay.pm:1100 lib/RT/Group_Overlay.pm:1109 lib/RT/Group_Overlay.pm:1160 lib/RT/Group_Overlay.pm:1164 lib/RT/Group_Overlay.pm:1170 lib/RT/Group_Overlay.pm:423 lib/RT/Group_Overlay.pm:515 lib/RT/Group_Overlay.pm:593 lib/RT/Group_Overlay.pm:601 lib/RT/Group_Overlay.pm:698 lib/RT/Group_Overlay.pm:702 lib/RT/Group_Overlay.pm:708 lib/RT/Group_Overlay.pm:901 lib/RT/Group_Overlay.pm:905 lib/RT/Group_Overlay.pm:918 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:934 lib/RT/Scrip_Overlay.pm:125 lib/RT/Scrip_Overlay.pm:136 lib/RT/Scrip_Overlay.pm:201 lib/RT/Scrip_Overlay.pm:441 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:87 lib/RT/Template_Overlay.pm:93 lib/RT/Ticket_Overlay.pm:1386 lib/RT/Ticket_Overlay.pm:1396 lib/RT/Ticket_Overlay.pm:1410 lib/RT/Ticket_Overlay.pm:1544 lib/RT/Ticket_Overlay.pm:1553 lib/RT/Ticket_Overlay.pm:1566 lib/RT/Ticket_Overlay.pm:1915 lib/RT/Ticket_Overlay.pm:2053 lib/RT/Ticket_Overlay.pm:2217 lib/RT/Ticket_Overlay.pm:2286 lib/RT/Ticket_Overlay.pm:2647 lib/RT/Ticket_Overlay.pm:2728 lib/RT/Ticket_Overlay.pm:2832 lib/RT/Ticket_Overlay.pm:2847 lib/RT/Ticket_Overlay.pm:3046 lib/RT/Ticket_Overlay.pm:3056 lib/RT/Ticket_Overlay.pm:3061 lib/RT/Ticket_Overlay.pm:3284 lib/RT/Ticket_Overlay.pm:3288 lib/RT/Ticket_Overlay.pm:3487 lib/RT/Ticket_Overlay.pm:3649 lib/RT/Ticket_Overlay.pm:3701 lib/RT/Ticket_Overlay.pm:3907 lib/RT/Transaction_Overlay.pm:415 lib/RT/Transaction_Overlay.pm:422 lib/RT/Transaction_Overlay.pm:451 lib/RT/Transaction_Overlay.pm:458 lib/RT/User_Overlay.pm:1084 lib/RT/User_Overlay.pm:1532 lib/RT/User_Overlay.pm:692 lib/RT/User_Overlay.pm:727 lib/RT/User_Overlay.pm:983 msgid "Permission Denied" msgstr "æƒé™ä¸è¶³" @@ -4217,11 +4377,27 @@ msgstr "代ç†äººç¾¤ç»„" msgid "Personal groups:" msgstr "代ç†äººç¾¤ç»„:" -#: html/Work/Preferences/Info:21 +#: html/Work/Preferences/Info:24 msgid "PersonalHomepage" msgstr "个人首页" #: NOT FOUND IN SOURCE +msgid "Phase 1: Create/Rename Groups (%1)" +msgstr "第一阶段:群组建立åŠæ”¹å (%1)" + +#: NOT FOUND IN SOURCE +msgid "Phase 2: Disable/Enable Groups (%1)" +msgstr "第二阶段:群组åœç”¨åŠå¯ç”¨ (%1)" + +#: NOT FOUND IN SOURCE +msgid "Phase 3: Create/Rename Users (%1)" +msgstr "第三阶段:使用者建立åŠæ”¹å (%1)" + +#: NOT FOUND IN SOURCE +msgid "Phase 4: Disable/Enable Users (%1)" +msgstr "第四阶段:使用者åœç”¨åŠå¯ç”¨ (%1)" + +#: NOT FOUND IN SOURCE msgid "Phone" msgstr "电è¯" @@ -4229,11 +4405,11 @@ msgstr "电è¯" msgid "Phone number" msgstr "电è¯å·ç " -#: html/Admin/Users/Modify.html:155 html/User/Prefs.html:48 html/Work/Preferences/Info:27 +#: html/Admin/Users/Modify.html:155 html/User/Prefs.html:60 html/Work/Preferences/Info:32 msgid "Phone numbers" msgstr "电è¯å·ç " -#: html/Edit/Users/Add.html:3 html/Work/Delegates/Add.html:3 html/Work/Delegates/Info:34 html/Work/Tickets/ModifyPeople.html:2 +#: html/Edit/Queues/Basic/Add.html:3 html/Edit/Queues/Basic/Top:55 html/Edit/Users/Add.html:3 html/Work/Delegates/Add.html:3 html/Work/Delegates/Info:34 html/Work/Tickets/ModifyPeople.html:2 msgid "Pick" msgstr "挑选" @@ -4245,7 +4421,7 @@ msgstr "出å‘地点" msgid "Placeholder" msgstr "尚未完工" -#: html/Edit/Elements/PickUsers:31 html/Edit/Elements/PickUsers:44 html/Edit/Elements/SelectCustomFieldType:3 html/Work/Elements/SelectOwner:3 html/Work/Tickets/Elements/EditCustomField:104 html/Work/Tickets/Elements/EditCustomField:185 html/Work/Tickets/Elements/EditCustomField:75 html/Work/Tickets/Elements/EditCustomFieldEntries:66 html/Work/Tickets/Elements/EditCustomFieldEntries:73 +#: html/Edit/Elements/PickUsers:31 html/Edit/Elements/PickUsers:44 html/Edit/Elements/SelectCustomFieldType:3 html/Work/Elements/SelectOwner:3 html/Work/Tickets/Elements/EditCustomField:187 html/Work/Tickets/Elements/EditCustomFieldEntry:24 html/Work/Tickets/Elements/EditCustomFieldEntry:35 msgid "Please Select" msgstr "请选择" @@ -4262,6 +4438,10 @@ msgid "Please select a queue's workflow" msgstr "请选择表å•æµç¨‹" #: NOT FOUND IN SOURCE +msgid "Please select one of the category types above." +msgstr "请从上é¢é€‰æ‹©ä¸€é¡¹åˆ†ç±»ã€‚" + +#: NOT FOUND IN SOURCE msgid "Please select role" msgstr "请选择角色" @@ -4273,19 +4453,19 @@ msgstr "ç»è¥è§„ç« " msgid "Position" msgstr "èŒåŠ¡" -#: html/Edit/Users/Info:43 +#: NOT FOUND IN SOURCE msgid "Position Level" msgstr "èŒç‰" -#: html/Edit/Elements/PickUsers:41 html/Edit/Global/UserRight/List:13 html/Edit/Global/UserRight/Top:23 html/Edit/Users/Add.html:41 html/Edit/Users/List:11 html/Edit/Users/Top:22 html/Work/Delegates/Add.html:26 html/Work/Delegates/Info:84 html/Work/Overview/Info:66 +#: html/Edit/Elements/PickUsers:41 html/Edit/Global/UserRight/List:13 html/Edit/Global/UserRight/Top:23 html/Edit/Queues/Basic/Add.html:26 html/Edit/Users/Add.html:41 html/Work/Delegates/Add.html:26 html/Work/Delegates/Info:84 html/Work/Overview/Info:66 msgid "Position Name" msgstr "èŒåŠ¡å称" -#: html/Edit/Global/UserRight/List:14 html/Edit/Global/UserRight/Top:33 html/Edit/Users/List:12 html/Edit/Users/Top:32 +#: html/Edit/Global/UserRight/List:14 html/Edit/Global/UserRight/Top:33 msgid "Position Number" msgstr "èŒåŠ¡ä»£ç " -#: html/Edit/Users/Info:44 +#: NOT FOUND IN SOURCE msgid "Position Rank" msgstr "èŒçº§" @@ -4293,7 +4473,7 @@ msgstr "èŒçº§" msgid "Pref" msgstr "å好" -#: html/Edit/Elements/104Top:25 html/Elements/Header:51 html/Elements/Tabs:52 html/SelfService/Elements/Tabs:50 html/SelfService/Prefs.html:24 html/User/Prefs.html:24 html/User/Prefs.html:27 html/Work/Elements/Tab:41 +#: html/Edit/Elements/104Top:26 html/Elements/Header:51 html/Elements/Tabs:52 html/SelfService/Elements/Tabs:50 html/SelfService/Prefs.html:24 html/User/Prefs.html:24 html/User/Prefs.html:27 html/Work/Elements/Tab:43 msgid "Preferences" msgstr "å好" @@ -4322,7 +4502,7 @@ msgstr "优先顺ä½" msgid "Principal %1 not found." msgstr "找ä¸åˆ°å•ä½ %1。" -#: html/Search/Elements/PickRestriction:53 html/Ticket/Create.html:153 html/Ticket/Elements/EditBasics:53 html/Ticket/Elements/ShowBasics:38 html/Work/Search/PickRestriction:34 lib/RT/Tickets_Overlay.pm:1042 +#: html/Search/Elements/PickRestriction:53 html/Ticket/Create.html:153 html/Ticket/Elements/EditBasics:53 html/Ticket/Elements/ShowBasics:38 html/Work/Search/PickRestriction:34 html/Work/Tickets/Elements/EditBasics:41 lib/RT/Tickets_Overlay.pm:1061 msgid "Priority" msgstr "优先顺ä½" @@ -4330,11 +4510,11 @@ msgstr "优先顺ä½" msgid "Priority starts at" msgstr "优先顺ä½èµ·å§‹å€¼" -#: etc/initialdata:43 +#: etc/initialdata:25 msgid "Privileged" msgstr "内部æˆå‘˜" -#: html/Admin/Users/Modify.html:270 html/User/Prefs.html:162 html/Work/Preferences/Info:153 +#: html/Admin/Users/Modify.html:272 html/User/Prefs.html:200 html/Work/Preferences/Info:164 #. (loc_fuzzy($msg)) msgid "Privileged status: %1" msgstr "内部æˆå‘˜çŠ¶æ€ï¼š%1" @@ -4347,11 +4527,19 @@ msgstr "内部æˆå‘˜" msgid "Process Status" msgstr "处ç†çŠ¶æ€" -#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53 etc/initialdata:77 +#: html/Edit/Queues/List:10 +msgid "Project Name" +msgstr "项目å称" + +#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59 msgid "Pseudogroup for internal use" msgstr "内部用的虚拟群组" -#: html/Work/Preferences/Info:64 +#: html/Edit/Queues/List:11 +msgid "Public Description" +msgstr "公开说明" + +#: html/Work/Preferences/Info:70 msgid "Public Info" msgstr "公开信æ¯" @@ -4359,11 +4547,15 @@ msgstr "公开信æ¯" msgid "Public Service" msgstr "公共事务区" +#: NOT FOUND IN SOURCE +msgid "Purging stale data: %1" +msgstr "移除过期数æ®: %1" + #: html/Edit/Users/Search.html:4 msgid "Query" msgstr "查询" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:166 html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Elements/Quicksearch:28 html/Search/Elements/PickRestriction:45 html/SelfService/Create.html:32 html/Ticket/Create.html:37 html/Ticket/Elements/EditBasics:63 html/Ticket/Elements/ShowBasics:42 html/User/Elements/DelegateRights:79 html/Work/Elements/MyApprovals:10 html/Work/Elements/MyRequests:11 html/Work/Elements/MyTickets:11 html/Work/Elements/Quicksearch:14 html/Work/Search/PickRestriction:26 lib/RT/Tickets_Overlay.pm:883 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:166 html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Elements/Quicksearch:28 html/Search/Elements/PickRestriction:45 html/SelfService/Create.html:32 html/Ticket/Create.html:37 html/Ticket/Elements/EditBasics:63 html/Ticket/Elements/ShowBasics:42 html/User/Elements/DelegateRights:79 html/Work/Elements/MyApprovals:10 html/Work/Elements/MyRequests:17 html/Work/Elements/MyTickets:17 html/Work/Elements/Quicksearch:14 html/Work/Search/PickRestriction:26 html/Work/Tickets/Elements/EditBasics:16 lib/RT/Tickets_Overlay.pm:902 msgid "Queue" msgstr "表å•" @@ -4381,19 +4573,19 @@ msgstr "找ä¸åˆ°è¡¨å• '%1'\\n" msgid "Queue Keyword Selections" msgstr "表å•å…³é”®è¯é€‰å–" -#: html/Admin/Elements/ModifyQueue:30 html/Admin/Queues/Modify.html:42 html/Edit/Queues/Basic/Top:12 html/Edit/Queues/Basic/index.html:36 html/Edit/Queues/Global:21 html/Edit/Queues/List:6 html/Edit/Users/Queue:10 html/Work/Delegates/List:6 html/Work/Elements/List:11 html/Work/Queues/List:5 html/Work/Tickets/Create.html:20 html/Work/Tickets/Elements/ShowBasics:6 +#: html/Admin/Elements/ModifyQueue:30 html/Admin/Queues/Modify.html:42 html/Edit/Queues/Basic/Top:13 html/Edit/Queues/Basic/index.html:36 html/Edit/Queues/Global:21 html/Edit/Queues/List:20 html/Edit/Users/Queue:10 html/Work/Delegates/List:6 html/Work/Elements/List:11 html/Work/Queues/List:5 html/Work/Tickets/Create.html:21 html/Work/Tickets/Elements/ShowBasics:6 msgid "Queue Name" msgstr "表å•å称" -#: html/Edit/Queues/List:8 html/Work/Elements/List:25 html/Work/Queues/List:7 html/Work/Tickets/Create.html:33 html/Work/Tickets/Elements/ShowBasics:19 +#: html/Edit/Queues/List:22 html/Work/Elements/List:25 html/Work/Queues/List:7 html/Work/Tickets/Create.html:34 html/Work/Tickets/Elements/ShowBasics:19 msgid "Queue Owner" msgstr "业务承办人" -#: html/Edit/Queues/Basic/Top:35 +#: html/Edit/Queues/Basic/Top:38 msgid "Queue Priority" msgstr "优先ç‰çº§" -#: html/Edit/Global/GroupRight/Top:24 html/Edit/Global/UserRight/Top:43 html/Edit/Users/Queue:11 html/Edit/Users/index.html:124 +#: html/Edit/Global/GroupRight/Top:24 html/Edit/Global/UserRight/Top:43 html/Edit/Users/Queue:11 html/Edit/Users/index.html:97 msgid "Queue Rights" msgstr "表å•æƒé™" @@ -4401,7 +4593,7 @@ msgstr "表å•æƒé™" msgid "Queue Scrips" msgstr "表å•æ‰‹ç»" -#: html/Edit/Elements/Tab:36 +#: html/Edit/Elements/Tab:38 msgid "Queue Setup" msgstr "表å•è®¾å®š" @@ -4413,11 +4605,11 @@ msgstr "表å•å·²å˜åœ¨" msgid "Queue could not be created" msgstr "æ— æ³•æ–°å¢žè¡¨å•" -#: html/Edit/Queues/autohandler:8 html/Ticket/Create.html:204 html/Work/Tickets/Create.html:176 +#: html/Edit/Queues/autohandler:8 html/Ticket/Create.html:208 html/Work/Tickets/Create.html:180 msgid "Queue could not be loaded." msgstr "æ— æ³•åŠ è½½è¡¨å•" -#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:283 +#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:283 lib/RT/StyleGuide.pod:789 msgid "Queue created" msgstr "表å•æ–°å¢žå®Œæ¯•" @@ -4446,7 +4638,7 @@ msgstr "表å•ä¸€è§ˆ" msgid "RT %1" msgstr "RT %1" -#: docs/design_docs/string-extraction-guide.txt:70 +#: docs/design_docs/string-extraction-guide.txt:70 lib/RT/StyleGuide.pod:776 #. ($RT::VERSION, $RT::rtname) msgid "RT %1 for %2" msgstr "%2:RT %1 版" @@ -4562,11 +4754,15 @@ msgstr "系统è¿è¡Œè§’色" msgid "RT::Ticket-Role" msgstr "申请å•è¿è¡Œè§’色" -#: html/Work/Tickets/Elements/ShowTransaction:11 +#: html/Work/Tickets/Elements/ShowTransaction:14 msgid "RT_System" msgstr "系统讯æ¯" -#: html/Admin/Users/Modify.html:57 html/Admin/Users/Prefs.html:51 html/User/Prefs.html:43 html/Work/Preferences/Info:18 +#: html/Edit/Global/CustomField/SelectWritable:7 +msgid "Read Only" +msgstr "åªè¯»" + +#: html/Admin/Users/Modify.html:57 html/Admin/Users/Prefs.html:51 html/Edit/Elements/SelectUsers:5 html/Edit/Users/List:6 html/User/Prefs.html:47 html/Work/Preferences/Info:18 msgid "Real Name" msgstr "真实姓å" @@ -4574,15 +4770,35 @@ msgstr "真实姓å" msgid "RealName" msgstr "真实姓å" -#: html/Work/Approvals/Display.html:27 html/Work/Tickets/Update.html:85 +#: html/Work/Approvals/Display.html:30 html/Work/Tickets/Update.html:81 msgid "Really reject this ticket?" msgstr "您确定è¦é©³å›žè¿™å¼ 申请å•å—?" -#: html/Ticket/Create.html:184 html/Ticket/Elements/BulkLinks:50 html/Ticket/Elements/EditLinks:138 html/Ticket/Elements/EditLinks:93 html/Ticket/Elements/ShowLinks:70 html/Work/Search/BulkLinks:26 +#: lib/RT/Transaction_Overlay.pm:592 +#. ($value) +msgid "Reference by %1 added" +msgstr "å·²åŠ å…¥ %1 为å‚考本申请å•" + +#: lib/RT/Transaction_Overlay.pm:629 +#. ($value) +msgid "Reference by %1 deleted" +msgstr "已移除 %1 为å‚考本申请å•" + +#: lib/RT/Transaction_Overlay.pm:589 +#. ($value) +msgid "Reference to %1 added" +msgstr "å·²åŠ å…¥å‚è€ƒç”³è¯·å• %1" + +#: lib/RT/Transaction_Overlay.pm:626 +#. ($value) +msgid "Reference to %1 deleted" +msgstr "已移除å‚è€ƒç”³è¯·å• %1" + +#: html/Ticket/Create.html:185 html/Ticket/Elements/BulkLinks:50 html/Ticket/Elements/EditLinks:121 html/Ticket/Elements/EditLinks:81 html/Ticket/Elements/ShowLinks:70 html/Work/Search/BulkLinks:26 html/Work/Tickets/Elements/EditLinks:125 html/Work/Tickets/Elements/EditLinks:81 html/Work/Tickets/Elements/ShowLinks:38 msgid "Referred to by" msgstr "被å‚考" -#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:183 html/Ticket/Elements/BulkLinks:46 html/Ticket/Elements/EditLinks:134 html/Ticket/Elements/EditLinks:79 html/Ticket/Elements/ShowLinks:60 html/Work/Search/BulkLinks:22 +#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:184 html/Ticket/Elements/BulkLinks:46 html/Ticket/Elements/EditLinks:117 html/Ticket/Elements/EditLinks:72 html/Ticket/Elements/ShowLinks:60 html/Work/Search/BulkLinks:22 html/Work/Tickets/Elements/EditLinks:121 html/Work/Tickets/Elements/EditLinks:67 html/Work/Tickets/Elements/ShowLinks:33 msgid "Refers to" msgstr "å‚考" @@ -4607,7 +4823,7 @@ msgstr "æ›´æ–°" msgid "Refresh this page every %1 minutes." msgstr "æ¯ %1 分钟更新页é¢" -#: html/Ticket/Create.html:173 html/Ticket/Elements/ShowSummary:61 html/Ticket/ModifyAll.html:56 +#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:61 html/Ticket/ModifyAll.html:56 msgid "Relationships" msgstr "关系" @@ -4627,7 +4843,7 @@ msgstr "移除副本" msgid "Remove Requestor" msgstr "移除申请人" -#: html/Ticket/Elements/ShowTransaction:160 html/Ticket/Elements/Tabs:121 html/Work/Tickets/Display.html:31 html/Work/Tickets/Elements/ShowTransaction:106 +#: html/Ticket/Elements/ShowTransaction:172 html/Ticket/Elements/Tabs:121 html/Work/Tickets/Display.html:54 html/Work/Tickets/Elements/ShowTransaction:115 msgid "Reply" msgstr "回å¤" @@ -4639,15 +4855,15 @@ msgstr "对申请å•è¿›è¡Œå›žå¤" msgid "ReplyToTicket" msgstr "回å¤ç”³è¯·å•" -#: html/Edit/Users/Info:46 +#: NOT FOUND IN SOURCE msgid "Report to Duty" msgstr "上下ç刷å¡" -#: html/Edit/Users/Info:34 +#: NOT FOUND IN SOURCE msgid "Reported on" msgstr "到èŒæ—¥æœŸ" -#: etc/initialdata:62 html/Ticket/Update.html:39 html/Work/Elements/List:21 html/Work/Elements/MyApprovals:12 html/Work/Elements/SelectSearch:30 html/Work/Tickets/Elements/ShowBasics:54 lib/RT/ACE_Overlay.pm:86 +#: etc/initialdata:44 html/Ticket/Update.html:39 html/Work/Elements/List:21 html/Work/Elements/MyApprovals:12 html/Work/Elements/MyTickets:20 html/Work/Elements/SelectSearch:31 html/Work/Tickets/Elements/ShowBasics:62 lib/RT/ACE_Overlay.pm:86 msgid "Requestor" msgstr "申请人" @@ -4675,7 +4891,7 @@ msgstr "申请人" msgid "RequestorAddresses" msgstr "申请人地å€" -#: html/SelfService/Create.html:40 html/Ticket/Create.html:55 html/Ticket/Elements/EditPeople:47 html/Ticket/Elements/ShowPeople:30 +#: html/SelfService/Create.html:40 html/Ticket/Create.html:55 html/Ticket/Elements/EditPeople:47 html/Ticket/Elements/ShowPeople:30 html/Work/Tickets/Elements/EditPeople:38 msgid "Requestors" msgstr "申请人" @@ -4687,7 +4903,7 @@ msgstr "申请å•å¤„ç†æœŸé™" msgid "Reset" msgstr "é‡è®¾" -#: html/Admin/Users/Modify.html:158 html/User/Prefs.html:49 html/Work/Preferences/Info:29 +#: html/Admin/Users/Modify.html:158 html/User/Prefs.html:63 html/Work/Preferences/Info:34 msgid "Residence" msgstr "ä½å¤„" @@ -4695,16 +4911,16 @@ msgstr "ä½å¤„" msgid "Resolution" msgstr "解决状æ€" -#: html/Ticket/Elements/Tabs:131 html/Work/Tickets/Display.html:34 +#: html/Ticket/Elements/Tabs:131 html/Work/Tickets/Display.html:57 msgid "Resolve" msgstr "解决" -#: html/Ticket/Update.html:136 html/Work/Tickets/Update.html:120 +#: html/Ticket/Update.html:137 #. ($Ticket->id, $Ticket->Subject) msgid "Resolve ticket #%1 (%2)" msgstr "è§£å†³ç”³è¯·å• #%1 (%2)" -#: etc/initialdata:331 html/Elements/SelectDateType:27 lib/RT/Ticket_Overlay.pm:1178 +#: etc/initialdata:308 html/Elements/SelectDateType:27 lib/RT/Ticket_Overlay.pm:1215 msgid "Resolved" msgstr "已解决" @@ -4712,7 +4928,7 @@ msgstr "已解决" msgid "Response to requestors" msgstr "回å¤ç”³è¯·äºº" -#: html/Edit/Users/Info:45 +#: NOT FOUND IN SOURCE msgid "Responsibility Type" msgstr "责任区分" @@ -4720,11 +4936,11 @@ msgstr "责任区分" msgid "Results" msgstr "结果" -#: html/Search/Elements/PickRestriction:104 html/Work/Search/PickRestriction:84 +#: html/Search/Elements/PickRestriction:104 html/Work/Search/PickRestriction:90 msgid "Results per page" msgstr "æ¯é¡µåˆ—å‡ºå‡ ç¬”ç»“æžœ" -#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:99 html/User/Prefs.html:71 html/Work/Preferences/Info:51 +#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:99 html/User/Prefs.html:94 html/Work/Preferences/Info:56 msgid "Retype Password" msgstr "å†æ¬¡è¾“å…¥å£ä»¤" @@ -4764,17 +4980,17 @@ msgstr "æƒé™æ’¤æ¶ˆå®Œæ¯•" msgid "Rights" msgstr "æƒé™åŠä»£ç†äºº" -#: lib/RT/Interface/Web.pm:794 +#: lib/RT/Interface/Web.pm:857 #. ($object_type) msgid "Rights could not be granted for %1" msgstr "æ— æ³•å°†æƒé™èµ‹äºˆ %1" -#: lib/RT/Interface/Web.pm:827 +#: lib/RT/Interface/Web.pm:887 #. ($object_type) msgid "Rights could not be revoked for %1" msgstr "æ— æ³•æ’¤æ¶ˆ %1 çš„æƒé™" -#: html/Edit/Groups/Member:55 html/Edit/Groups/Members/List:10 +#: html/Edit/Groups/Member:54 html/Edit/Groups/Members/List:10 msgid "Role Members" msgstr "角色æˆå‘˜" @@ -4790,19 +5006,19 @@ msgstr "角色" msgid "RootApproval" msgstr "交由系统管ç†å‘˜ç¾æ ¸" -#: html/Edit/Global/Workflow/Action:27 +#: html/Edit/Global/Workflow/Action:23 msgid "Run Approval" msgstr "ç¾æ ¸æ‰§è¡Œ" -#: html/Edit/Global/Basic/Top:72 +#: html/Edit/Global/Basic/Top:81 msgid "SMTPDebug" msgstr "SMTP 侦错纪录" -#: html/Edit/Global/Basic/Top:58 +#: html/Edit/Global/Basic/Top:63 msgid "SMTPFrom" msgstr "SMTP 寄件地å€" -#: html/Edit/Global/Basic/Top:56 +#: html/Edit/Global/Basic/Top:61 msgid "SMTPServer" msgstr "SMTP æœåŠ¡å™¨" @@ -4814,7 +5030,7 @@ msgstr "星期å…" msgid "Sat." msgstr "星期å…" -#: html/Edit/Elements/104Buttons:72 html/Work/Preferences/index.html:35 +#: html/Edit/Elements/104Buttons:83 html/Work/Preferences/index.html:33 html/Work/Tickets/Elements/EditBasics:63 html/Work/Tickets/Elements/EditLinks:133 html/Work/Tickets/Elements/EditPeople:51 msgid "Save" msgstr "储å˜" @@ -4840,7 +5056,7 @@ msgstr "讯æ¯é€šçŸ¥åŠ¨ä½œ" msgid "Scrip Condition" msgstr "讯æ¯é€šçŸ¥æ¡ä»¶" -#: lib/RT/Scrip_Overlay.pm:175 +#: lib/RT/Scrip_Overlay.pm:180 msgid "Scrip Created" msgstr "手ç»æ–°å¢žå®Œæ¯•" @@ -4848,7 +5064,7 @@ msgstr "手ç»æ–°å¢žå®Œæ¯•" msgid "Scrip Name" msgstr "讯æ¯å称" -#: html/Admin/Elements/EditScrips:83 +#: html/Admin/Elements/EditScrips:85 msgid "Scrip deleted" msgstr "手ç»åˆ 除完毕" @@ -4856,7 +5072,7 @@ msgstr "手ç»åˆ 除完毕" msgid "Scrips" msgstr "手ç»" -#: html/Edit/Global/autohandler:9 html/Edit/Queues/autohandler:20 +#: html/Edit/Global/autohandler:9 html/Edit/Queues/autohandler:24 msgid "Scrips " msgstr "讯æ¯é€šçŸ¥" @@ -4868,7 +5084,7 @@ msgstr "%1 的手ç»\\n" msgid "Scrips which apply to all queues" msgstr "适用于所有表å•çš„手ç»" -#: html/Edit/Elements/104Buttons:75 html/Elements/SimpleSearch:26 html/Search/Elements/PickRestriction:125 html/Ticket/Elements/Tabs:158 html/Work/Elements/Tab:43 html/Work/Search/PickRestriction:102 +#: html/Edit/Elements/104Buttons:86 html/Elements/SimpleSearch:26 html/Search/Elements/PickRestriction:125 html/Ticket/Elements/Tabs:158 html/Work/Elements/Tab:45 html/Work/Search/PickRestriction:108 msgid "Search" msgstr "查询" @@ -4884,7 +5100,7 @@ msgstr "ç¾æ ¸å•æŸ¥è¯¢" msgid "Second-" msgstr "二" -#: html/Edit/Users/Info:41 +#: NOT FOUND IN SOURCE msgid "Second-level Users" msgstr "二阶主管员工" @@ -4964,7 +5180,7 @@ msgstr "多é‡é€‰é¡¹" msgid "SelectSingle" msgstr "å•ä¸€é€‰é¡¹" -#: html/Edit/Elements/PickUsers:85 html/Edit/Users/Add.html:78 +#: html/Edit/Elements/PickUsers:87 html/Edit/Users/Add.html:78 msgid "Selected users:" msgstr "新增对象:" @@ -4972,39 +5188,39 @@ msgstr "新增对象:" msgid "Self Service" msgstr "自助æœåŠ¡" -#: etc/initialdata:131 +#: etc/initialdata:113 msgid "Send mail to all watchers" msgstr "寄信给所有视察员" -#: etc/initialdata:127 +#: etc/initialdata:109 msgid "Send mail to all watchers as a \"comment\"" msgstr "以评论方å¼å¯„信给所有视察员" -#: etc/initialdata:122 +#: etc/initialdata:104 msgid "Send mail to requestors and Ccs" msgstr "寄信给申请人åŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:117 +#: etc/initialdata:99 msgid "Send mail to requestors and Ccs as a comment" msgstr "以评论方å¼å¯„信给申请人åŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:96 +#: etc/initialdata:78 msgid "Sends a message to the requestors" msgstr "寄信给申请人" -#: etc/initialdata:135 etc/initialdata:139 +#: etc/initialdata:117 etc/initialdata:121 msgid "Sends mail to explicitly listed Ccs and Bccs" msgstr "寄信给特定的副本åŠå¯†ä»¶å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:112 +#: etc/initialdata:94 msgid "Sends mail to the administrative Ccs" msgstr "寄信给管ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:108 +#: etc/initialdata:90 msgid "Sends mail to the administrative Ccs as a comment" msgstr "以评论寄信给管ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:100 etc/initialdata:104 +#: etc/initialdata:82 etc/initialdata:86 msgid "Sends mail to the owner" msgstr "寄信给申请人" @@ -5020,7 +5236,11 @@ msgstr "09" msgid "September" msgstr "ä¹æœˆ" -#: html/Edit/Users/Info:39 +#: NOT FOUND IN SOURCE +msgid "Setting %1's 'Disabled' property to %2" +msgstr "%1 的「åœç”¨ã€å±žæ€§å·²è®¾ä¸º %2" + +#: NOT FOUND IN SOURCE msgid "Shift Type" msgstr "ç别属性" @@ -5088,7 +5308,7 @@ msgstr "登记æˆä¸ºç”³è¯·äººæˆ–副本收件人" msgid "Sign up as a ticket or queue AdminCc" msgstr "登记æˆä¸ºç®¡ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: html/Admin/Elements/ModifyUser:38 html/Admin/Users/Modify.html:190 html/Admin/Users/Prefs.html:31 html/User/Prefs.html:111 html/Work/Preferences/Info:106 +#: html/Admin/Elements/ModifyUser:38 html/Admin/Users/Modify.html:190 html/Admin/Users/Prefs.html:31 html/Edit/Users/Info:52 html/User/Prefs.html:148 html/Work/Preferences/Info:113 msgid "Signature" msgstr "ç¾åæ¡£" @@ -5100,7 +5320,7 @@ msgstr "使用者:%1" msgid "Single" msgstr "å•ä¸€" -#: html/Elements/Header:50 +#: html/Edit/Elements/104Top:21 html/Elements/Header:50 msgid "Skip Menu" msgstr "略过选å•" @@ -5112,7 +5332,7 @@ msgstr "顺åº" msgid "Sort key" msgstr "排åºæ–¹å¼" -#: html/Search/Elements/PickRestriction:108 html/Work/Search/PickRestriction:89 +#: html/Search/Elements/PickRestriction:108 html/Work/Search/PickRestriction:95 msgid "Sort results by" msgstr "结果排åºæ–¹å¼" @@ -5120,7 +5340,7 @@ msgstr "结果排åºæ–¹å¼" msgid "SortOrder" msgstr "排åºé¡ºåº" -#: html/Work/Elements/List:8 html/Work/Elements/MyApprovals:11 +#: html/Admin/Elements/EditScrip:80 html/Edit/Global/Scrip/Top:75 html/Work/Elements/List:8 html/Work/Elements/MyApprovals:11 msgid "Stage" msgstr "å…³å¡" @@ -5140,7 +5360,7 @@ msgstr "延宕" msgid "Start page" msgstr "首页" -#: html/Elements/SelectDateType:26 html/Ticket/Elements/EditDates:31 html/Ticket/Elements/ShowDates:34 +#: html/Elements/SelectDateType:26 html/Ticket/Elements/EditDates:31 html/Ticket/Elements/ShowDates:35 html/Work/Tickets/Elements/EditBasics:35 msgid "Started" msgstr "实际起始日" @@ -5148,7 +5368,7 @@ msgstr "实际起始日" msgid "Started date '%1' could not be parsed" msgstr "æ— æ³•è§£è¯»èµ·å§‹æ—¥æœŸ '%1" -#: html/Elements/SelectDateType:30 html/Ticket/Create.html:165 html/Ticket/Elements/EditDates:26 html/Ticket/Elements/ShowDates:30 +#: html/Elements/SelectDateType:30 html/Ticket/Create.html:165 html/Ticket/Elements/EditDates:26 html/Ticket/Elements/ShowDates:31 html/Work/Tickets/Elements/EditBasics:26 msgid "Starts" msgstr "应起始日" @@ -5160,19 +5380,19 @@ msgstr "应起始日" msgid "Starts date '%1' could not be parsed" msgstr "æ— æ³•è§£è¯»èµ·å§‹æ—¥æœŸ '%1" -#: html/Admin/Elements/ModifyUser:81 html/Admin/Users/Modify.html:137 html/User/Prefs.html:93 html/Work/Preferences/Info:82 +#: html/Admin/Elements/ModifyUser:81 html/Admin/Users/Modify.html:137 html/User/Prefs.html:126 html/Work/Preferences/Info:85 msgid "State" msgstr "å·ž" -#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Search/Elements/PickRestriction:73 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:30 html/Ticket/Create.html:41 html/Ticket/Elements/EditBasics:37 html/Ticket/Elements/ShowBasics:30 html/Ticket/Update.html:59 html/Work/Elements/List:15 html/Work/Elements/MyRequests:12 html/Work/Elements/MyTickets:12 html/Work/Search/PickRestriction:54 html/Work/Tickets/Update.html:22 lib/RT/Ticket_Overlay.pm:1172 lib/RT/Tickets_Overlay.pm:908 +#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Search/Elements/PickRestriction:73 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:30 html/Ticket/Create.html:41 html/Ticket/Elements/EditBasics:37 html/Ticket/Elements/ShowBasics:30 html/Ticket/Update.html:59 html/Work/Elements/List:15 html/Work/Elements/MyRequests:18 html/Work/Elements/MyTickets:18 html/Work/Search/PickRestriction:54 html/Work/Tickets/Elements/EditBasics:19 html/Work/Tickets/Update.html:22 lib/RT/Ticket_Overlay.pm:1209 lib/RT/Tickets_Overlay.pm:927 msgid "Status" msgstr "现况" -#: etc/initialdata:317 +#: etc/initialdata:294 msgid "Status Change" msgstr "现况改å˜æ—¶" -#: lib/RT/Transaction_Overlay.pm:528 +#: lib/RT/Transaction_Overlay.pm:477 #. ($self->loc($self->OldValue), $self->loc($self->NewValue)) msgid "Status changed from %1 to %2" msgstr "现况从 %1 改为 %2" @@ -5193,25 +5413,25 @@ msgstr "强制承办申请å•" msgid "StealTicket" msgstr "强制承办申请å•" -#: lib/RT/Transaction_Overlay.pm:587 +#: lib/RT/Transaction_Overlay.pm:545 #. ($Old->Name) msgid "Stolen from %1 " -msgstr "被 %1 å¼ºåˆ¶æ›´æ¢ " +msgstr "承办人从 %1 强制更æ¢" -#: html/Edit/Groups/Member:69 +#: html/Edit/Groups/Member:68 msgid "Subgroup" msgstr "å群组" -#: html/Elements/MyRequests:28 html/Elements/MyTickets:28 html/Search/Bulk.html:135 html/Search/Elements/PickRestriction:42 html/SelfService/Create.html:56 html/SelfService/Elements/MyRequests:27 html/SelfService/Update.html:31 html/Ticket/Create.html:83 html/Ticket/Elements/EditBasics:27 html/Ticket/ModifyAll.html:78 html/Ticket/Update.html:75 html/Work/Elements/MyApprovals:9 html/Work/Elements/MyRequests:10 html/Work/Elements/MyTickets:10 html/Work/Search/Bulk.html:87 html/Work/Search/PickRestriction:22 html/Work/Tickets/Create.html:122 lib/RT/Ticket_Overlay.pm:1168 lib/RT/Tickets_Overlay.pm:987 +#: html/Elements/MyRequests:28 html/Elements/MyTickets:28 html/Search/Bulk.html:135 html/Search/Elements/PickRestriction:42 html/SelfService/Create.html:56 html/SelfService/Elements/MyRequests:27 html/SelfService/Update.html:31 html/Ticket/Create.html:83 html/Ticket/Elements/EditBasics:27 html/Ticket/ModifyAll.html:78 html/Ticket/Update.html:75 html/Work/Elements/MyApprovals:9 html/Work/Elements/MyRequests:16 html/Work/Elements/MyTickets:16 html/Work/Search/Bulk.html:87 html/Work/Search/PickRestriction:22 html/Work/Tickets/Elements/AddSubject:8 html/Work/Tickets/Elements/EditBasics:8 html/Work/Tickets/Elements/ShowBasics:36 html/Work/Tickets/Elements/ShowSubject:8 lib/RT/Ticket_Overlay.pm:1205 lib/RT/Tickets_Overlay.pm:1006 msgid "Subject" msgstr "主题" -#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:609 +#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/StyleGuide.pod:795 lib/RT/Transaction_Overlay.pm:567 #. ($self->Data) msgid "Subject changed to %1" msgstr "æ ‡é¢˜å·²æ”¹ä¸º %1" -#: html/Elements/Submit:58 html/Work/Search/Bulk.html:103 +#: html/Edit/Users/Info:71 html/Elements/Submit:58 html/Work/Search/Bulk.html:103 msgid "Submit" msgstr "é€å‡º" @@ -5219,7 +5439,7 @@ msgstr "é€å‡º" msgid "Submit Workflow" msgstr "é€å‡ºæµç¨‹" -#: lib/RT/Group_Overlay.pm:748 +#: lib/RT/Group_Overlay.pm:746 msgid "Succeeded" msgstr "设定æˆåŠŸ" @@ -5235,6 +5455,18 @@ msgstr "星期日" msgid "SuperUser" msgstr "系统管ç†å‘˜" +#: html/Edit/Global/Basic/Top:29 +msgid "Sync now" +msgstr "执行åŒæ¥" + +#: html/Edit/Global/Basic/Top:87 +msgid "Sync104HRMS" +msgstr "自动åŒæ¥104HRMS" + +#: NOT FOUND IN SOURCE +msgid "Synchronizing HRMS data. This may take a while..." +msgstr "æ£åœ¨åŒæ¥åŒ– HRMS 人事系统数æ®ã€‚请ç¨å¾…..." + #: html/User/Elements/DelegateRights:76 msgid "System" msgstr "系统" @@ -5243,7 +5475,7 @@ msgstr "系统" msgid "System Defined" msgstr "系统定义" -#: html/Admin/Elements/SelectRights:80 lib/RT/ACE_Overlay.pm:566 lib/RT/Interface/Web.pm:793 lib/RT/Interface/Web.pm:826 +#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:566 lib/RT/Interface/Web.pm:856 lib/RT/Interface/Web.pm:886 msgid "System Error" msgstr "系统错误" @@ -5255,7 +5487,7 @@ msgstr "系统错误。设定æƒé™å¤±è´¥ã€‚" msgid "System Error. right not granted" msgstr "系统错误。设定æƒé™å¤±è´¥ã€‚" -#: html/Edit/Users/index.html:122 +#: html/Edit/Users/index.html:95 msgid "System Rights" msgstr "系统æƒé™" @@ -5279,14 +5511,18 @@ msgstr "系统群组" msgid "SystemInternal" msgstr "系统内部用" -#: etc/initialdata:59 etc/initialdata:65 etc/initialdata:71 +#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53 msgid "SystemRolegroup for internal use" msgstr "内部使用的系统角色群组" -#: lib/RT/CurrentUser.pm:319 +#: lib/RT/CurrentUser.pm:318 msgid "TEST_STRING" msgstr "TEST_STRING" +#: NOT FOUND IN SOURCE +msgid "TabbedUI" +msgstr "页ç¾æŽ¥å£" + #: html/Ticket/Elements/Tabs:142 msgid "Take" msgstr "å—ç†" @@ -5299,11 +5535,11 @@ msgstr "自行承办申请å•" msgid "TakeTicket" msgstr "自行承办申请å•" -#: lib/RT/Transaction_Overlay.pm:573 +#: lib/RT/Transaction_Overlay.pm:530 msgid "Taken" msgstr "å·²å—ç†" -#: html/Admin/Elements/EditScrip:80 +#: html/Admin/Elements/EditScrip:88 msgid "Template" msgstr "模æ¿" @@ -5328,7 +5564,7 @@ msgstr "通知模æ¿å称" msgid "Template deleted" msgstr "模æ¿å·²åˆ 除" -#: lib/RT/Scrip_Overlay.pm:152 +#: lib/RT/Scrip_Overlay.pm:156 msgid "Template not found" msgstr "找ä¸åˆ°æ¨¡æ¿" @@ -5336,7 +5572,7 @@ msgstr "找ä¸åˆ°æ¨¡æ¿" msgid "Template not found\\n" msgstr "找ä¸åˆ°æ¨¡æ¿\\n" -#: lib/RT/Template_Overlay.pm:352 +#: lib/RT/Template_Overlay.pm:359 msgid "Template parsed" msgstr "模æ¿å‰–æžå®Œæ¯•" @@ -5344,7 +5580,7 @@ msgstr "模æ¿å‰–æžå®Œæ¯•" msgid "Templates" msgstr "模æ¿" -#: html/Edit/Global/autohandler:8 html/Edit/Queues/autohandler:19 +#: html/Edit/Global/autohandler:8 html/Edit/Queues/autohandler:23 msgid "Templates " msgstr "通知模æ¿" @@ -5352,7 +5588,7 @@ msgstr "通知模æ¿" msgid "Templates for %1\\n" msgstr "找ä¸åˆ° %1 的模æ¿\\n" -#: lib/RT/Interface/Web.pm:894 +#: lib/RT/Interface/Web.pm:954 msgid "That is already the current value" msgstr "å·²ç»æ˜¯ç›®å‰å—段的值" @@ -5360,7 +5596,7 @@ msgstr "å·²ç»æ˜¯ç›®å‰å—段的值" msgid "That is not a value for this custom field" msgstr "è¿™ä¸æ˜¯è¯¥è‡ªè®¢å—段的值" -#: lib/RT/Ticket_Overlay.pm:1908 +#: lib/RT/Ticket_Overlay.pm:1926 msgid "That is the same value" msgstr "åŒæ ·çš„值" @@ -5373,7 +5609,7 @@ msgstr "这项å•ä½å·²ç»æ‹¥æœ‰è¯¥æƒé™" msgid "That principal is already a %1 for this queue" msgstr "这项å•ä½å·²ç»æ˜¯è¿™ä¸ªè¡¨å•çš„ %1" -#: lib/RT/Ticket_Overlay.pm:1442 +#: lib/RT/Ticket_Overlay.pm:1460 #. ($self->loc($args{'Type'})) msgid "That principal is already a %1 for this ticket" msgstr "这项å•ä½å·²ç»æ˜¯è¿™ä»½ç”³è¯·å•çš„ %1" @@ -5383,16 +5619,16 @@ msgstr "这项å•ä½å·²ç»æ˜¯è¿™ä»½ç”³è¯·å•çš„ %1" msgid "That principal is not a %1 for this queue" msgstr "这项å•ä½ä¸æ˜¯è¿™ä¸ªè¡¨å•çš„ %1" -#: lib/RT/Ticket_Overlay.pm:1559 +#: lib/RT/Ticket_Overlay.pm:1577 #. ($args{'Type'}) msgid "That principal is not a %1 for this ticket" msgstr "这项å•ä½ä¸æ˜¯è¿™ä»½ç”³è¯·å•çš„ %1" -#: lib/RT/Ticket_Overlay.pm:1904 +#: lib/RT/Ticket_Overlay.pm:1922 msgid "That queue does not exist" msgstr "æ¤è¡¨å•ä¸å˜åœ¨" -#: lib/RT/Ticket_Overlay.pm:3246 +#: lib/RT/Ticket_Overlay.pm:3293 msgid "That ticket has unresolved dependencies" msgstr "这份申请å•æœ‰å°šæœªè§£å†³çš„附属申请å•" @@ -5400,27 +5636,27 @@ msgstr "这份申请å•æœ‰å°šæœªè§£å†³çš„附属申请å•" msgid "That user already has that right" msgstr "使用者已具有该项æƒé™" -#: lib/RT/Ticket_Overlay.pm:3056 +#: lib/RT/Ticket_Overlay.pm:3097 msgid "That user already owns that ticket" msgstr "该使用者已ç»æ‰¿åŠžè¿™ä»½ç”³è¯·å•" -#: lib/RT/Ticket_Overlay.pm:3028 +#: lib/RT/Ticket_Overlay.pm:3069 msgid "That user does not exist" msgstr "使用者ä¸å˜åœ¨" -#: lib/RT/User_Overlay.pm:374 +#: lib/RT/User_Overlay.pm:381 msgid "That user is already privileged" msgstr "è¿™å使用者已ç»æ˜¯å†…部æˆå‘˜" -#: lib/RT/User_Overlay.pm:395 +#: lib/RT/User_Overlay.pm:402 msgid "That user is already unprivileged" msgstr "è¿™å使用者属于éžå†…部æˆå‘˜ç¾¤ç»„" -#: lib/RT/User_Overlay.pm:387 +#: lib/RT/User_Overlay.pm:394 msgid "That user is now privileged" msgstr "ä½¿ç”¨è€…åŠ å…¥å†…éƒ¨æˆå‘˜ç¾¤ç»„完毕" -#: lib/RT/User_Overlay.pm:408 +#: lib/RT/User_Overlay.pm:415 msgid "That user is now unprivileged" msgstr "è¿™åä½¿ç”¨è€…å·²åŠ å…¥éžå†…部æˆå‘˜ç¾¤ç»„" @@ -5428,7 +5664,7 @@ msgstr "è¿™åä½¿ç”¨è€…å·²åŠ å…¥éžå†…部æˆå‘˜ç¾¤ç»„" msgid "That user is now unprivilegedileged" msgstr "è¿™åä½¿ç”¨è€…å·²åŠ å…¥éžå†…部æˆå‘˜ç¾¤ç»„" -#: lib/RT/Ticket_Overlay.pm:3049 +#: lib/RT/Ticket_Overlay.pm:3090 msgid "That user may not own tickets in that queue" msgstr "使用者å¯èƒ½æ²¡æœ‰æ‰¿åŠžè¡¨å•é‡Œçš„申请å•" @@ -5448,7 +5684,7 @@ msgstr "申请å•çš„副本收件人" msgid "The administrative CC of a ticket" msgstr "申请å•çš„管ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: lib/RT/Ticket_Overlay.pm:2235 +#: lib/RT/Ticket_Overlay.pm:2255 msgid "The comment has been recorded" msgstr "评论已被纪录" @@ -5460,7 +5696,7 @@ msgstr "下列命令会找到 'general' 表å•å†…所有è¿ä½œä¸çš„申请å•ï¼Œå msgid "The following commands were not proccessed:\\n\\n" msgstr "以下命令未被执行:\\n\\n" -#: lib/RT/Interface/Web.pm:897 +#: lib/RT/Interface/Web.pm:957 msgid "The new value has been set." msgstr "æ–°çš„å—段值设定完æˆã€‚" @@ -5488,7 +5724,7 @@ msgstr "ç”³è¯·å• %1 %2 (%3)\\n" msgid "This tool allows the user to run arbitrary perl modules from within RT." msgstr "æ¤å·¥å…·ç¨‹åºä¼šè®©ä½¿ç”¨è€…ç»ç”± RT 执行任æ„命令。" -#: lib/RT/Transaction_Overlay.pm:251 +#: lib/RT/Transaction_Overlay.pm:200 msgid "This transaction appears to have no content" msgstr "æ¤é¡¹æ›´åŠ¨æŠ¥å‘Šæ²¡æœ‰å†…容" @@ -5509,7 +5745,7 @@ msgstr "星期四" msgid "Thu." msgstr "星期四" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:163 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:163 html/Edit/Global/Workflow/Condition:24 msgid "Ticket" msgstr "申请å•" @@ -5531,7 +5767,7 @@ msgstr "æ›´æ–°ç”³è¯·å• #%1 的全部信æ¯ï¼š%2" msgid "Ticket #%1: %2" msgstr "ç”³è¯·å• #%1: %2" -#: lib/RT/Ticket_Overlay.pm:595 lib/RT/Ticket_Overlay.pm:616 +#: lib/RT/Ticket_Overlay.pm:632 lib/RT/Ticket_Overlay.pm:653 #. ($self->Id, $QueueObj->Name) msgid "Ticket %1 created in queue '%2'" msgstr "ç”³è¯·å• #%1 æˆåŠŸæ–°å¢žäºŽ '%2' 表å•" @@ -5541,12 +5777,12 @@ msgstr "ç”³è¯·å• #%1 æˆåŠŸæ–°å¢žäºŽ '%2' 表å•" msgid "Ticket %1 loaded\\n" msgstr "åŠ è½½ç”³è¯·å• %1\\n" -#: html/Search/Bulk.html:212 html/Work/Search/Bulk.html:169 +#: html/Search/Bulk.html:213 html/Work/Search/Bulk.html:169 #. ($Ticket->Id,$_) msgid "Ticket %1: %2" msgstr "ç”³è¯·å• %1:%2" -#: html/Edit/Queues/Basic/Top:28 html/Edit/Queues/List:16 html/Work/Queues/List:9 +#: html/Edit/Queues/Basic/Top:30 html/Edit/Queues/List:30 html/Work/Queues/List:9 msgid "Ticket Due" msgstr "表å•å¤„ç†æœŸé™" @@ -5567,11 +5803,11 @@ msgstr "申请å•ç¼–å·" msgid "Ticket Processing Due" msgstr "表å•è¿è¡ŒæœŸé™" -#: etc/initialdata:332 +#: etc/initialdata:309 msgid "Ticket Resolved" msgstr "申请å•å·²è§£å†³" -#: html/Edit/Queues/Basic/Top:18 html/Edit/Queues/Category/List:6 html/Edit/Queues/Category/Top:7 html/Edit/Queues/List:7 html/Edit/Queues/index.html:31 html/Work/Delegates/List:7 html/Work/Delegates/index.html:11 html/Work/Elements/List:12 html/Work/Elements/SelectSearch:9 html/Work/Queues/List:6 html/Work/Queues/Select.html:12 html/Work/Queues/index.html:11 html/Work/Tickets/Create.html:42 html/Work/Tickets/Elements/ShowBasics:33 +#: html/Edit/Queues/Basic/Top:20 html/Edit/Queues/Category/List:6 html/Edit/Queues/Category/Top:7 html/Edit/Queues/List:21 html/Work/Delegates/List:7 html/Work/Delegates/index.html:11 html/Work/Elements/List:12 html/Work/Elements/SelectSearch:9 html/Work/Queues/List:6 html/Work/Queues/Select.html:12 html/Work/Queues/index.html:11 html/Work/Tickets/Create.html:43 html/Work/Tickets/Elements/ShowBasics:34 msgid "Ticket Type" msgstr "表å•ç§ç±»" @@ -5579,19 +5815,19 @@ msgstr "表å•ç§ç±»" msgid "Ticket attachment" msgstr "申请å•é™„件" -#: lib/RT/Tickets_Overlay.pm:1166 +#: lib/RT/Tickets_Overlay.pm:1185 msgid "Ticket content" msgstr "申请å•å†…容" -#: lib/RT/Tickets_Overlay.pm:1212 +#: lib/RT/Tickets_Overlay.pm:1231 msgid "Ticket content type" msgstr "申请å•å†…容类别" -#: lib/RT/Ticket_Overlay.pm:485 lib/RT/Ticket_Overlay.pm:494 lib/RT/Ticket_Overlay.pm:504 lib/RT/Ticket_Overlay.pm:605 +#: lib/RT/Ticket_Overlay.pm:520 lib/RT/Ticket_Overlay.pm:529 lib/RT/Ticket_Overlay.pm:539 lib/RT/Ticket_Overlay.pm:642 msgid "Ticket could not be created due to an internal error" msgstr "å†…éƒ¨é”™è¯¯ï¼Œæ— æ³•æ–°å¢žç”³è¯·å•" -#: lib/RT/Transaction_Overlay.pm:520 +#: lib/RT/Transaction_Overlay.pm:469 msgid "Ticket created" msgstr "申请å•æ–°å¢žå®Œæ¯•" @@ -5599,7 +5835,7 @@ msgstr "申请å•æ–°å¢žå®Œæ¯•" msgid "Ticket creation failed" msgstr "申请å•æ–°å¢žå¤±è´¥" -#: lib/RT/Transaction_Overlay.pm:525 +#: lib/RT/Transaction_Overlay.pm:474 msgid "Ticket deleted" msgstr "申请å•åˆ 除完毕" @@ -5615,7 +5851,7 @@ msgstr "申请å•åˆ 除完毕" msgid "Ticket not found" msgstr "找ä¸åˆ°ç”³è¯·å•" -#: etc/initialdata:318 +#: etc/initialdata:295 msgid "Ticket status changed" msgstr "申请å•çŽ°å†µå·²æ”¹å˜" @@ -5627,16 +5863,24 @@ msgstr "申请å•è§†å¯Ÿå‘˜" msgid "Tickets" msgstr "申请å•" -#: lib/RT/Tickets_Overlay.pm:1383 +#: lib/RT/Tickets_Overlay.pm:1402 #. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'})) msgid "Tickets %1 %2" msgstr "ç”³è¯·å• %1 %2" -#: lib/RT/Tickets_Overlay.pm:1348 +#: lib/RT/Tickets_Overlay.pm:1367 #. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'})) msgid "Tickets %1 by %2" msgstr "ç”³è¯·å• %1 (%2)" +#: NOT FOUND IN SOURCE +msgid "Tickets I own" +msgstr "待处ç†çš„申请å•" + +#: NOT FOUND IN SOURCE +msgid "Tickets I requested" +msgstr "é€å‡ºçš„申请å•" + #: html/Elements/ViewUser:25 #. ($name) msgid "Tickets from %1" @@ -5646,15 +5890,15 @@ msgstr "%1 的申请å•" msgid "Tickets which depend on this approval:" msgstr "批准之åŽï¼Œå¯æŽ¥ç»å¤„ç†ï¼š" -#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:47 +#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:47 html/Work/Tickets/Elements/EditBasics:32 msgid "Time Left" msgstr "剩馀时间" -#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:42 +#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:42 html/Work/Tickets/Elements/EditBasics:24 msgid "Time Worked" msgstr "处ç†æ—¶é—´" -#: lib/RT/Tickets_Overlay.pm:1139 +#: lib/RT/Tickets_Overlay.pm:1158 msgid "Time left" msgstr "剩馀时间" @@ -5662,7 +5906,7 @@ msgstr "剩馀时间" msgid "Time to display" msgstr "显示时间" -#: lib/RT/Tickets_Overlay.pm:1115 +#: lib/RT/Tickets_Overlay.pm:1134 msgid "Time worked" msgstr "已处ç†æ—¶é—´" @@ -5670,7 +5914,7 @@ msgstr "已处ç†æ—¶é—´" msgid "TimeLeft" msgstr "剩馀时间" -#: lib/RT/Ticket_Overlay.pm:1173 +#: lib/RT/Ticket_Overlay.pm:1210 msgid "TimeWorked" msgstr "已处ç†æ—¶é—´" @@ -5682,32 +5926,40 @@ msgstr "产生这次更动的差异档:" msgid "To generate a diff of this commit:\\n" msgstr "产生这次更动的差异档:\\n" -#: lib/RT/Ticket_Overlay.pm:1176 +#: lib/RT/Ticket_Overlay.pm:1213 msgid "Told" msgstr "告知日期" -#: html/Edit/Elements/Page:46 +#: html/Edit/Elements/Page:47 msgid "Total" msgstr "页" -#: etc/initialdata:239 +#: etc/initialdata:237 msgid "Transaction" msgstr "更动" -#: lib/RT/Transaction_Overlay.pm:640 +#: lib/RT/Transaction_Overlay.pm:666 #. ($self->Data) msgid "Transaction %1 purged" msgstr "清除更动报告 %1" -#: lib/RT/Transaction_Overlay.pm:177 +#: lib/RT/Transaction_Overlay.pm:126 msgid "Transaction Created" msgstr "更动报告已新增" -#: lib/RT/Transaction_Overlay.pm:88 +#: lib/RT/Transaction_Overlay.pm:90 msgid "Transaction->Create couldn't, as you didn't specify a ticket id" msgstr "未指定申请å•ç¼–å·ï¼Œæ— 法新增更动" -#: lib/RT/Transaction_Overlay.pm:699 +#: NOT FOUND IN SOURCE +msgid "TransactionBatch" +msgstr "批次更动时" + +#: NOT FOUND IN SOURCE +msgid "TransactionCreate" +msgstr "新增更动时" + +#: lib/RT/Transaction_Overlay.pm:721 msgid "Transactions are immutable" msgstr "ä¸å¯æ›´æ”¹æ›´åŠ¨æŠ¥å‘Š" @@ -5723,7 +5975,7 @@ msgstr "星期二" msgid "Tue." msgstr "星期二" -#: html/Admin/Elements/EditCustomField:43 html/Admin/Elements/ModifyTemplateAsWorkflow:135 html/Ticket/Elements/AddWatchers:32 html/Ticket/Elements/AddWatchers:43 html/Ticket/Elements/AddWatchers:53 lib/RT/Ticket_Overlay.pm:1174 lib/RT/Tickets_Overlay.pm:959 +#: html/Admin/Elements/EditCustomField:43 html/Admin/Elements/ModifyTemplateAsWorkflow:135 html/Ticket/Elements/AddWatchers:32 html/Ticket/Elements/AddWatchers:43 html/Ticket/Elements/AddWatchers:53 lib/RT/Ticket_Overlay.pm:1211 lib/RT/Tickets_Overlay.pm:978 msgid "Type" msgstr "类别" @@ -5739,7 +5991,7 @@ msgstr "外部系统登入å¸å·" msgid "UnixUsername" msgstr "外部系统登入å¸å·" -#: lib/RT/Attachment_Overlay.pm:273 lib/RT/Attachment_Overlay.pm:303 +#: lib/RT/Attachment_Overlay.pm:281 lib/RT/Attachment_Overlay.pm:313 #. ($self->ContentEncoding) msgid "Unknown ContentEncoding %1" msgstr "ä¸å¯è§£çš„内容文å—ç¼–ç æ–¹å¼ %1" @@ -5748,11 +6000,11 @@ msgstr "ä¸å¯è§£çš„内容文å—ç¼–ç æ–¹å¼ %1" msgid "Unlimited" msgstr "全数显示" -#: etc/initialdata:50 +#: etc/initialdata:32 msgid "Unprivileged" msgstr "éžå†…部æˆå‘˜" -#: lib/RT/Transaction_Overlay.pm:569 +#: lib/RT/Transaction_Overlay.pm:526 msgid "Untaken" msgstr "未被å—ç†" @@ -5760,7 +6012,7 @@ msgstr "未被å—ç†" msgid "Up" msgstr "上一页" -#: html/Elements/MyTickets:63 html/Search/Bulk.html:32 html/Work/Elements/MyTickets:72 html/Work/Search/Bulk.html:10 html/Work/Tickets/Elements/EditCustomFieldEntries:82 +#: html/Elements/MyTickets:63 html/Search/Bulk.html:32 html/Work/Elements/MyTickets:83 html/Work/Search/Bulk.html:10 html/Work/Tickets/Elements/EditCustomFieldEntries:63 msgid "Update" msgstr "处ç†" @@ -5784,7 +6036,7 @@ msgstr "更新电å邮件信箱" msgid "Update name" msgstr "æ›´æ–°å¸å·" -#: lib/RT/Interface/Web.pm:409 +#: lib/RT/Interface/Web.pm:467 msgid "Update not recorded." msgstr "更新未被记录" @@ -5804,21 +6056,21 @@ msgstr "更新申请å•" msgid "Update ticket # %1" msgstr "æ›´æ–°ç”³è¯·å• # %1" -#: html/SelfService/Update.html:24 html/SelfService/Update.html:46 +#: html/SelfService/Update.html:24 html/SelfService/Update.html:63 #. ($Ticket->id) msgid "Update ticket #%1" msgstr "æ›´æ–°ç”³è¯·å• #%1" -#: html/Ticket/Update.html:138 html/Work/Tickets/Update.html:122 +#: html/Ticket/Update.html:139 #. ($Ticket->id, $Ticket->Subject) msgid "Update ticket #%1 (%2)" msgstr "æ›´æ–°ç”³è¯·å• #%1 (%2)" -#: lib/RT/Interface/Web.pm:407 +#: lib/RT/Interface/Web.pm:465 msgid "Update type was neither correspondence nor comment." msgstr "更新的内容并éžç”³è¯·å•å›žå¤ä¹Ÿä¸æ˜¯è¯„论" -#: html/Elements/SelectDateType:32 html/Ticket/Elements/ShowDates:50 lib/RT/Ticket_Overlay.pm:1177 +#: html/Elements/SelectDateType:32 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1214 msgid "Updated" msgstr "å‰æ¬¡æ›´æ–°" @@ -5842,31 +6094,31 @@ msgstr "找ä¸åˆ°ä½¿ç”¨è€… '%1'" msgid "User '%1' not found\\n" msgstr "找ä¸åˆ°ä½¿ç”¨è€… '%1'\\n" -#: etc/initialdata:142 etc/initialdata:209 +#: etc/initialdata:124 etc/initialdata:191 msgid "User Defined" msgstr "使用者自订" -#: html/Admin/Users/Prefs.html:58 html/Edit/Users/List:13 html/Edit/Users/Top:42 +#: html/Admin/Users/Prefs.html:58 msgid "User ID" msgstr "使用者 ID" -#: html/Elements/SelectUsers:25 +#: html/Edit/Elements/SelectUsers:3 html/Elements/SelectUsers:25 msgid "User Id" msgstr "使用者 ID" -#: html/Edit/Elements/PickUsers:12 html/Edit/Global/UserRight/List:7 html/Edit/Global/UserRight/Top:9 html/Edit/Users/Add.html:13 html/Edit/Users/List:5 html/Edit/Users/Search.html:23 html/Edit/Users/Top:8 html/Work/Delegates/Info:60 html/Work/Tickets/Cc:10 +#: html/Edit/Elements/PickUsers:12 html/Edit/Global/UserRight/List:7 html/Edit/Global/UserRight/Top:9 html/Edit/Users/Add.html:13 html/Edit/Users/Search.html:23 html/Work/Delegates/Info:60 html/Work/Tickets/Cc:10 msgid "User Number" msgstr "员工编å·" -#: html/Admin/Elements/GroupTabs:46 html/Admin/Elements/QueueTabs:59 html/Admin/Elements/SystemTabs:46 html/Admin/Global/index.html:58 html/Edit/Global/autohandler:11 html/Edit/Queues/autohandler:22 +#: html/Admin/Elements/GroupTabs:46 html/Admin/Elements/QueueTabs:59 html/Admin/Elements/SystemTabs:46 html/Admin/Global/index.html:58 html/Edit/Global/autohandler:11 html/Edit/Queues/autohandler:26 msgid "User Rights" msgstr "使用者æƒé™" -#: html/Edit/Elements/Tab:32 +#: html/Edit/Elements/Tab:34 msgid "User Setup" msgstr "使用者设定" -#: html/Edit/Users/Info:38 +#: NOT FOUND IN SOURCE msgid "User Shift" msgstr "员工ç别" @@ -5875,18 +6127,34 @@ msgstr "员工ç别" msgid "User could not be created: %1" msgstr "æ— æ³•æ–°å¢žä½¿ç”¨è€…ï¼š%1" -#: lib/RT/User_Overlay.pm:321 +#: lib/RT/User_Overlay.pm:326 msgid "User created" msgstr "使用者新增完毕" +#: NOT FOUND IN SOURCE +msgid "User created: %1" +msgstr "使用者 %1 新增完毕" + +#: NOT FOUND IN SOURCE +msgid "User created: %1 (%2)" +msgstr "使用者 %1 (%2) 新增完毕" + #: html/Admin/Global/GroupRights.html:66 html/Admin/Groups/GroupRights.html:53 html/Admin/Queues/GroupRights.html:68 msgid "User defined groups" msgstr "使用者定义的群组" +#: lib/RT/User_Overlay.pm:580 lib/RT/User_Overlay.pm:597 +msgid "User loaded" +msgstr "å·²åŠ è½½ä½¿ç”¨è€…" + #: NOT FOUND IN SOURCE msgid "User notified" msgstr "已通知使用者" +#: NOT FOUND IN SOURCE +msgid "User renamed from %1 to %2" +msgstr "使用者 %1 已改å为 %2" + #: html/Admin/Users/Prefs.html:24 html/Admin/Users/Prefs.html:28 msgid "User view" msgstr "使用者ç§äººæ•°æ®" @@ -5899,7 +6167,7 @@ msgstr "使用者自定" msgid "Username" msgstr "å¸å·" -#: html/Admin/Elements/SelectNewGroupMembers:25 html/Admin/Elements/Tabs:31 html/Admin/Groups/Members.html:54 html/Admin/Queues/People.html:67 html/Admin/index.html:28 html/User/Groups/Members.html:57 html/Work/Tickets/Elements/ShowTransaction:8 +#: html/Admin/Elements/SelectNewGroupMembers:25 html/Admin/Elements/Tabs:31 html/Admin/Groups/Members.html:54 html/Admin/Queues/People.html:67 html/Admin/index.html:28 html/Edit/Groups/Admin:9 html/User/Groups/Members.html:57 html/Work/Tickets/Elements/ShowTransaction:11 msgid "Users" msgstr "使用者" @@ -5907,7 +6175,7 @@ msgstr "使用者" msgid "Users matching search criteria" msgstr "符åˆæŸ¥è¯¢æ¡ä»¶çš„使用者" -#: html/Search/Elements/PickRestriction:50 html/Work/Search/PickRestriction:31 +#: NOT FOUND IN SOURCE msgid "ValueOfQueue" msgstr "选择表å•" @@ -5927,7 +6195,7 @@ msgstr "以管ç†å‘˜å‰¯æœ¬æ”¶ä»¶äººèº«ä»½è§†å¯Ÿ" msgid "Watcher loaded" msgstr "æˆåŠŸåŠ 载视察员信æ¯" -#: html/Admin/Elements/QueueTabs:41 +#: html/Admin/Elements/QueueTabs:41 html/Edit/Elements/SelectQueues:5 msgid "Watchers" msgstr "视察员" @@ -5943,55 +6211,55 @@ msgstr "星期三" msgid "Wed." msgstr "星期三" -#: etc/initialdata:533 etc/upgrade/2.1.71:161 html/Edit/Elements/CreateApprovalsQueue:135 +#: etc/initialdata:503 etc/upgrade/2.1.71:161 html/Edit/Elements/CreateApprovalsQueue:135 msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket" msgstr "当申请å•é€šè¿‡æ‰€æœ‰ç¾æ ¸åŽï¼Œå°†æ¤è®¯æ¯å›žå¤åˆ°åŽŸç”³è¯·å•" -#: etc/initialdata:497 etc/upgrade/2.1.71:135 html/Edit/Elements/CreateApprovalsQueue:107 +#: etc/initialdata:467 etc/upgrade/2.1.71:135 html/Edit/Elements/CreateApprovalsQueue:107 msgid "When a ticket has been approved by any approver, add correspondence to the original ticket" msgstr "当申请å•é€šè¿‡æŸé¡¹ç¾æ ¸åŽï¼Œå°†æ¤è®¯æ¯å›žå¤åˆ°åŽŸç”³è¯·å•" -#: etc/initialdata:156 +#: etc/initialdata:138 msgid "When a ticket is created" msgstr "新增申请å•æ—¶" -#: etc/initialdata:428 etc/upgrade/2.1.71:79 html/Edit/Elements/CreateApprovalsQueue:51 +#: etc/initialdata:400 etc/upgrade/2.1.71:79 html/Edit/Elements/CreateApprovalsQueue:51 msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval" msgstr "ç¾æ ¸å•æ–°å¢žä¹‹åŽï¼Œé€šçŸ¥åº”å—ç†çš„承办人åŠç®¡ç†å‘˜å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata:161 +#: etc/initialdata:143 msgid "When anything happens" msgstr "当任何事情å‘生时" -#: etc/initialdata:202 +#: etc/initialdata:184 msgid "Whenever a ticket is resolved" msgstr "当申请å•è§£å†³æ—¶" -#: etc/initialdata:188 +#: etc/initialdata:170 msgid "Whenever a ticket's owner changes" msgstr "当申请å•æ›´æ¢æ‰¿åŠžäººæ—¶" -#: etc/initialdata:196 +#: etc/initialdata:178 msgid "Whenever a ticket's queue changes" msgstr "当申请å•æ›´æ¢è¡¨å•æ—¶" -#: etc/initialdata:180 +#: etc/initialdata:162 msgid "Whenever a ticket's status changes" msgstr "当申请å•æ›´æ–°çŽ°å†µæ—¶" -#: etc/initialdata:210 +#: etc/initialdata:192 msgid "Whenever a user-defined condition occurs" msgstr "当使用者自订的情况å‘生时" -#: etc/initialdata:174 +#: etc/initialdata:156 msgid "Whenever comments come in" msgstr "当评论é€è¾¾æ—¶" -#: etc/initialdata:167 +#: etc/initialdata:149 msgid "Whenever correspondence comes in" msgstr "当回å¤é€è¾¾æ—¶" -#: html/Admin/Users/Modify.html:163 html/User/Prefs.html:51 html/Work/Preferences/Info:31 +#: html/Admin/Users/Modify.html:163 html/User/Prefs.html:67 html/Work/Preferences/Info:36 msgid "Work" msgstr "å…¬å¸" @@ -6020,23 +6288,35 @@ msgstr "æµç¨‹ç»“æŸ" msgid "Workflow deleted" msgstr "æµç¨‹å·²åˆ 除" -#: html/Edit/Global/autohandler:10 html/Edit/Queues/autohandler:21 +#: html/Edit/Global/autohandler:10 html/Edit/Queues/autohandler:25 msgid "Workflows" msgstr "æµç¨‹" -#: html/Edit/Global/Basic/Top:25 +#: html/Edit/Global/CustomField/SelectWritable:5 +msgid "Writable" +msgstr "å¯è¯»å†™" + +#: html/autohandler:144 +msgid "XXX CHANGEME You are not an authorized user" +msgstr "XXX CHANGEME 您是未ç»æŽˆæƒçš„使用者" + +#: html/Edit/Global/Basic/Top:25 html/Edit/Queues/Basic/Top:82 msgid "Yes" msgstr "是" -#: lib/RT/Ticket_Overlay.pm:3159 +#: lib/RT/Ticket_Overlay.pm:3200 msgid "You already own this ticket" msgstr "您已是这份申请å•çš„承办人" -#: html/autohandler:122 +#: html/autohandler:136 msgid "You are not an authorized user" msgstr "您ä¸æ˜¯è¢«æŽˆæƒçš„使用者" -#: lib/RT/Ticket_Overlay.pm:3041 +#: html/Ticket/Elements/ShowTransaction:81 +msgid "You can access it with the Download button on the right." +msgstr "您å¯ä»¥æŒ‰å³æ–¹çš„「下载ã€é”®æ¥å–得。" + +#: lib/RT/Ticket_Overlay.pm:3082 msgid "You can only reassign tickets that you own or that are unowned" msgstr "祇能é‡æ–°æŒ‡æ´¾æ‚¨æ‰€æ‰¿åŠžæˆ–是没有承办人的申请å•" @@ -6044,7 +6324,7 @@ msgstr "祇能é‡æ–°æŒ‡æ´¾æ‚¨æ‰€æ‰¿åŠžæˆ–是没有承办人的申请å•" msgid "You don't have permission to view that ticket.\\n" msgstr "您没有看那份申请å•çš„æƒé™ã€‚\\n" -#: docs/design_docs/string-extraction-guide.txt:47 +#: docs/design_docs/string-extraction-guide.txt:47 lib/RT/StyleGuide.pod:760 #. ($num, $queue) msgid "You found %1 tickets in queue %2" msgstr "æ‚¨ä¼šåœ¨è¡¨å• %2 找到 %1 的申请å•" @@ -6057,11 +6337,11 @@ msgstr "您已注销 RT。" msgid "You have no permission to create tickets in that queue." msgstr "您没有在该表å•æ–°å¢žç”³è¯·å•çš„æƒé™ã€‚" -#: lib/RT/Ticket_Overlay.pm:1917 +#: lib/RT/Ticket_Overlay.pm:1935 msgid "You may not create requests in that queue." msgstr "您ä¸èƒ½åœ¨è¯¥è¡¨å•ä¸æ出申请。" -#: html/Edit/Global/Basic/Top:38 +#: html/Edit/Global/Basic/Top:42 msgid "You need to restart the Request Tracker service for saved changes to take effect." msgstr "您必须é‡æ–°æ¿€æ´» Request Tracker æœåŠ¡ï¼Œå‚¨å˜çš„更动æ‰ä¼šç”Ÿæ•ˆã€‚" @@ -6077,11 +6357,11 @@ msgstr "您æ出的 %1 申请å•" msgid "Your RT administrator has misconfigured the mail aliases which invoke RT" msgstr "RT 管ç†å‘˜å¯èƒ½è®¾é”™äº†ç”± RT å¯„å‡ºçš„é‚®ä»¶æ”¶ä»¶äººæ ‡å¤´æ¡£" -#: etc/initialdata:514 etc/upgrade/2.1.71:146 html/Edit/Elements/CreateApprovalsQueue:119 +#: etc/initialdata:484 etc/upgrade/2.1.71:146 html/Edit/Elements/CreateApprovalsQueue:119 msgid "Your request has been approved by %1. Other approvals may still be pending." msgstr "申请å•å·²ç”± %1 批准。å¯èƒ½è¿˜æœ‰å…¶å®ƒå¾…ç¾æ ¸çš„æ¥éª¤ã€‚" -#: etc/initialdata:552 etc/upgrade/2.1.71:180 html/Edit/Elements/CreateApprovalsQueue:154 +#: etc/initialdata:522 etc/upgrade/2.1.71:180 html/Edit/Elements/CreateApprovalsQueue:154 msgid "Your request has been approved." msgstr "您的申请å•å·²å®Œæˆç¾æ ¸ç¨‹åºã€‚" @@ -6089,19 +6369,19 @@ msgstr "您的申请å•å·²å®Œæˆç¾æ ¸ç¨‹åºã€‚" msgid "Your request was rejected" msgstr "您的申请å•å·²è¢«é©³å›ž" -#: etc/initialdata:455 +#: NOT FOUND IN SOURCE msgid "Your request was rejected by %1." msgstr "您的申请å•å·²è¢« %1 驳回。" -#: etc/upgrade/2.1.71:101 html/Edit/Elements/CreateApprovalsQueue:73 +#: etc/initialdata:427 etc/upgrade/2.1.71:101 html/Edit/Elements/CreateApprovalsQueue:73 msgid "Your request was rejected." msgstr "您的申请å•å·²è¢«é©³å›žã€‚" -#: html/autohandler:144 +#: html/autohandler:170 msgid "Your username or password is incorrect" msgstr "您的å¸å·æˆ–å£ä»¤æœ‰è¯¯" -#: html/Admin/Elements/ModifyUser:83 html/Admin/Users/Modify.html:143 html/User/Prefs.html:95 html/Work/Preferences/Info:84 +#: html/Admin/Elements/ModifyUser:83 html/Admin/Users/Modify.html:143 html/User/Prefs.html:130 html/Work/Preferences/Info:87 msgid "Zip" msgstr "邮政编ç " @@ -6117,6 +6397,10 @@ msgstr "过期" msgid "alert" msgstr "急讯" +#: NOT FOUND IN SOURCE +msgid "approving" +msgstr "å¾…ç¾æ ¸" + #: html/User/Elements/DelegateRights:58 #. ($right->PrincipalObj->Object->SelfDescription) msgid "as granted to %1" @@ -6138,11 +6422,11 @@ msgstr "内容" msgid "content-type" msgstr "类型" -#: lib/RT/Ticket_Overlay.pm:2304 +#: lib/RT/Ticket_Overlay.pm:2326 msgid "correspondence (probably) not sent" msgstr "申请å•å›žå¤(å¯èƒ½)未é€å‡º" -#: lib/RT/Ticket_Overlay.pm:2314 +#: lib/RT/Ticket_Overlay.pm:2336 msgid "correspondence sent" msgstr "申请å•å›žå¤å·²é€å‡º" @@ -6150,7 +6434,7 @@ msgstr "申请å•å›žå¤å·²é€å‡º" msgid "critical" msgstr "严é‡" -#: html/Admin/Elements/ModifyQueue:62 html/Admin/Queues/Modify.html:76 html/Edit/Queues/Basic/Top:31 html/Edit/Queues/List:18 html/Work/Queues/List:11 lib/RT/Date.pm:319 +#: html/Admin/Elements/ModifyQueue:62 html/Admin/Queues/Modify.html:76 html/Edit/Queues/Basic/Top:34 html/Edit/Queues/List:32 html/Work/Queues/List:11 lib/RT/Date.pm:319 msgid "days" msgstr "天" @@ -6219,11 +6503,11 @@ msgstr "ç¼–å·" msgid "info" msgstr "ä¿¡æ¯" -#: html/Elements/SelectBoolean:31 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:35 html/Search/Elements/PickRestriction:46 html/Search/Elements/PickRestriction:75 html/Search/Elements/PickRestriction:87 html/Work/Search/PickRestriction:27 html/Work/Search/PickRestriction:56 html/Work/Search/PickRestriction:69 +#: html/Elements/SelectBoolean:31 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:35 html/Search/Elements/PickRestriction:46 html/Search/Elements/PickRestriction:75 html/Search/Elements/PickRestriction:87 html/Work/Search/PickRestriction:27 html/Work/Search/PickRestriction:56 html/Work/Search/PickRestriction:75 msgid "is" msgstr "是" -#: html/Elements/SelectBoolean:35 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88 html/Work/Search/PickRestriction:28 html/Work/Search/PickRestriction:57 html/Work/Search/PickRestriction:70 +#: html/Elements/SelectBoolean:35 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88 html/Work/Search/PickRestriction:28 html/Work/Search/PickRestriction:57 html/Work/Search/PickRestriction:76 msgid "isn't" msgstr "ä¸æ˜¯" @@ -6259,11 +6543,15 @@ msgstr "月" msgid "new" msgstr "新建立" +#: html/Admin/Elements/EditCustomFields:42 +msgid "no name" +msgstr "没有å称" + #: html/Admin/Elements/EditScrips:42 msgid "no value" msgstr "没有值" -#: html/Admin/Elements/EditQueueWatchers:26 html/Edit/Groups/Member:40 html/Edit/Groups/Members/Add.html:17 html/Edit/Groups/Members/List:8 html/Edit/Queues/Basic/Top:50 html/Edit/Queues/List:18 html/Ticket/Elements/EditWatchers:27 html/Work/Delegates/Info:37 html/Work/Delegates/Info:48 html/Work/Overview/Info:31 html/Work/Queues/List:11 html/Work/Tickets/Elements/ShowBasics:27 +#: html/Admin/Elements/EditQueueWatchers:26 html/Edit/Groups/Member:40 html/Edit/Groups/Members/Add.html:17 html/Edit/Groups/Members/List:8 html/Edit/Queues/List:32 html/Ticket/Elements/EditWatchers:27 html/Work/Delegates/Info:37 html/Work/Delegates/Info:48 html/Work/Overview/Info:31 html/Work/Queues/List:11 html/Work/Tickets/Elements/EditWatchers:5 html/Work/Tickets/Elements/ShowAttachments:30 html/Work/Tickets/Elements/ShowBasics:27 msgid "none" msgstr "æ— " @@ -6305,11 +6593,11 @@ msgstr "è¡¨å• %1 %2" msgid "rejected" msgstr "已驳回" -#: html/Work/Elements/SelectSearch:21 lib/RT/Queue_Overlay.pm:60 +#: lib/RT/Queue_Overlay.pm:60 msgid "resolved" msgstr "已处ç†" -#: html/Edit/Global/Basic/Top:48 +#: html/Edit/Global/Basic/Top:53 msgid "rtname" msgstr "æœåŠ¡å™¨å称" @@ -6335,16 +6623,21 @@ msgstr "系统群组 '%1'" msgid "the calling component did not specify why" msgstr "呼å«ç»„ä»¶æœªæŒ‡æ˜ŽåŽŸå› " +#: lib/RT/URI/fsck_com_rt.pm:234 +#. ($self->Object->Id) +msgid "ticket #%1" +msgstr "ç”³è¯·å• #%1" + #: lib/RT/Group_Overlay.pm:209 #. ($self->Instance, $self->Type) msgid "ticket #%1 %2" msgstr "ç”³è¯·å• #%1 %2" -#: html/Work/Elements/SelectSearch:27 +#: html/Work/Elements/SelectSearch:28 msgid "till" msgstr "至" -#: html/Edit/Elements/PickUsers:15 html/Edit/Global/Workflow/Condition:30 html/Edit/Users/Add.html:16 html/Edit/Users/Search.html:26 html/Work/Tickets/Cc:13 +#: html/Edit/Elements/PickUsers:15 html/Edit/Global/Workflow/Condition:31 html/Edit/Users/Add.html:16 html/Edit/Users/Search.html:26 html/Work/Tickets/Cc:13 msgid "to" msgstr "到" @@ -6357,7 +6650,7 @@ msgstr "真" msgid "undescribed group %1" msgstr "没有æ述的群组 %1" -#: html/Work/Elements/SelectSearch:19 +#: NOT FOUND IN SOURCE msgid "unresolved" msgstr "未处ç†" diff --git a/rt/lib/RT/I18N/zh_tw.po b/rt/lib/RT/I18N/zh_tw.po index 8c8c86e1f..6688b6a89 100644 --- a/rt/lib/RT/I18N/zh_tw.po +++ b/rt/lib/RT/I18N/zh_tw.po @@ -1,4 +1,4 @@ -# Traditional Chinese localization catalog for Request Tracker (RT) +# Chinese localization catalog for Request Tracker (RT) msgid "" msgstr "" "Last-Translator: Autrijus Tang <autrijus@autrijus.org>\n" @@ -40,7 +40,7 @@ msgstr "%*(%1) 件尚未解決的申請單" msgid "%1 %2" msgstr "%1 %2" -#: lib/RT/Tickets_Overlay.pm:771 +#: lib/RT/Tickets_Overlay.pm:790 #. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'}) msgid "%1 %2 %3" msgstr "%1 %2 %3" @@ -50,10 +50,11 @@ msgstr "%1 %2 %3" msgid "%1 %2 %3 %4:%5:%6 %7" msgstr "%7-%2-%3 %4:%5:%6 %1" -#: lib/RT/Ticket_Overlay.pm:3532 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Overlay.pm:599 +#: lib/RT/Ticket_Overlay.pm:3588 lib/RT/Transaction_Overlay.pm:514 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Vendor.pm:19 #. ($cf->Name, $new_value->Content) #. ($field, $self->NewValue) #. ($self->Field, $principal->Object->Name) +#. ($field, $new_value) msgid "%1 %2 added" msgstr "%2 已新增為 %1" @@ -62,16 +63,18 @@ msgstr "%2 已新增為 %1" msgid "%1 %2 ago" msgstr "%1 %2 之å‰" -#: lib/RT/Ticket_Overlay.pm:3538 lib/RT/Transaction_Overlay.pm:564 +#: lib/RT/Ticket_Overlay.pm:3594 lib/RT/Transaction_Overlay.pm:521 lib/RT/Transaction_Vendor.pm:25 #. ($cf->Name, $old_value, $new_value->Content) #. ($field, $self->OldValue, $self->NewValue) +#. ($field, $old_value, $new_value) msgid "%1 %2 changed to %3" msgstr "%1 已從 %2 改為 %3" -#: lib/RT/Ticket_Overlay.pm:3535 lib/RT/Transaction_Overlay.pm:560 lib/RT/Transaction_Overlay.pm:605 +#: lib/RT/Ticket_Overlay.pm:3591 lib/RT/Transaction_Overlay.pm:517 lib/RT/Transaction_Overlay.pm:563 lib/RT/Transaction_Vendor.pm:22 #. ($cf->Name, $old_value) #. ($field, $self->OldValue) #. ($self->Field, $principal->Object->Name) +#. ($field, $old_value) msgid "%1 %2 deleted" msgstr "%2 已自 %1 刪除" @@ -121,17 +124,17 @@ msgstr "%1 - 指定欲使用的æ¢ä»¶æ¨¡çµ„" msgid "%1 - Specify the search module you want to use" msgstr "%1 - 指定欲使用的查詢模組" -#: lib/RT/ScripAction_Overlay.pm:121 +#: lib/RT/ScripAction_Overlay.pm:122 #. ($self->Id) msgid "%1 ScripAction loaded" msgstr "載入手續 %1" -#: html/Edit/Elements/Page:48 +#: html/Edit/Elements/Page:49 #. (scalar $count) msgid "%1 Total" msgstr "å…± %1 ç†" -#: lib/RT/Ticket_Overlay.pm:3565 +#: lib/RT/Ticket_Overlay.pm:3621 #. ($args{'Value'}, $cf->Name) msgid "%1 added as a value for %2" msgstr "新增 %1 作為 %2 的值" @@ -154,13 +157,13 @@ msgstr "別å %1 需è¦å¯ç”¨çš„ç”³è«‹å–®ç·¨è™Ÿä»¥è™•ç† %3(出自 %2)" msgid "%1 appears to be a local object, but can't be found in the database" msgstr "%1 看來是個本地物件,å»ä¸åœ¨è³‡æ–™åº«è£¡" -#: html/Ticket/Elements/ShowDates:51 lib/RT/Transaction_Overlay.pm:481 +#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:430 #. ($self->BriefDescription , $self->CreatorObj->Name) #. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name) msgid "%1 by %2" msgstr "%1 (%2)" -#: lib/RT/Transaction_Overlay.pm:535 lib/RT/Transaction_Overlay.pm:624 lib/RT/Transaction_Overlay.pm:633 lib/RT/Transaction_Overlay.pm:636 +#: lib/RT/Transaction_Overlay.pm:484 lib/RT/Transaction_Overlay.pm:649 lib/RT/Transaction_Overlay.pm:658 lib/RT/Transaction_Overlay.pm:661 #. ($self->Field , ( $self->OldValue || $no_value ) , $self->NewValue) #. ($self->Field , $q1->Name , $q2->Name) #. ($self->Field, $t2->AsString, $t1->AsString) @@ -168,7 +171,7 @@ msgstr "%1 (%2)" msgid "%1 changed from %2 to %3" msgstr "%1 的值從 %2 改為 %3" -#: lib/RT/Interface/Web.pm:893 x:896 +#: lib/RT/Interface/Web.pm:953 msgid "%1 could not be set to %2." msgstr "無法將 %1 è¨å®šç‚º %2。" @@ -176,7 +179,7 @@ msgstr "無法將 %1 è¨å®šç‚º %2。" msgid "%1 couldn't init a transaction (%2)\\n" msgstr "%1 無法åˆå§‹æ›´æ–° (%2)\\n" -#: lib/RT/Ticket_Overlay.pm:2830 +#: lib/RT/Ticket_Overlay.pm:2880 #. ($self) msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent." msgstr "%1 無法將ç¾æ³è¨æˆå·²è§£æ±ºã€‚RT 資料庫內容å¯èƒ½ä¸ä¸€è‡´ã€‚" @@ -206,12 +209,12 @@ msgstr "%1 是從外部排程程å¼(如 cron)來å°ç”³è«‹å–®é€²è¡Œæ“ä½œçš„å·¥å… msgid "%1 is no longer a %2 for this queue." msgstr "%1 å·²ä¸å†æ˜¯æ¤è¡¨å–®çš„ %2。" -#: lib/RT/Ticket_Overlay.pm:1569 +#: lib/RT/Ticket_Overlay.pm:1596 #. ($principal->Object->Name, $args{'Type'}) msgid "%1 is no longer a %2 for this ticket." msgstr "%1 å·²ä¸å†æ˜¯æ¤ç”³è«‹å–®çš„ %2。" -#: lib/RT/Ticket_Overlay.pm:3621 +#: lib/RT/Ticket_Overlay.pm:3677 #. ($args{'Value'}, $cf->Name) msgid "%1 is no longer a value for custom field %2" msgstr "%1 å·²ä¸å†æ˜¯è‡ªè¨‚æ¬„ä½ %2 的值。" @@ -264,17 +267,17 @@ msgstr "%1 會解決在已解決群組裡æˆå“¡çš„申請單。" msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request." msgstr "如果 %1 起始申請單ä¾è³´æ–¼æŸå€‹éˆçµï¼Œæˆ–是æŸå€‹éˆçµçš„æˆå“¡ï¼Œå®ƒå°‡æœƒè¢«å»¶å®•ã€‚" -#: lib/RT/Transaction_Overlay.pm:433 +#: lib/RT/Transaction_Overlay.pm:382 lib/RT/Transaction_Vendor.pm:37 #. ($self) msgid "%1: no attachment specified" msgstr "%1:未指定附件" -#: html/Ticket/Elements/ShowTransaction:89 html/Work/Tickets/Elements/ShowTransaction:154 +#: html/Ticket/Elements/ShowTransaction:100 html/Work/Tickets/Elements/ShowTransaction:158 #. ($size) msgid "%1b" msgstr "%1 ä½å…ƒçµ„" -#: html/Ticket/Elements/ShowTransaction:86 html/Work/Tickets/Elements/ShowTransaction:151 +#: html/Ticket/Elements/ShowTransaction:97 html/Work/Tickets/Elements/ShowTransaction:155 #. (int($size/102.4)/10) msgid "%1k" msgstr "%1k ä½å…ƒçµ„" @@ -283,7 +286,7 @@ msgstr "%1k ä½å…ƒçµ„" msgid "%quant(%1,result) found" msgstr "找到 %1 é …çµæžœ" -#: lib/RT/Ticket_Overlay.pm:1158 +#: lib/RT/Ticket_Overlay.pm:1185 #. ($args{'Status'}) msgid "'%1' is an invalid value for status" msgstr "'%1' ä¸æ˜¯ä¸€å€‹åˆæ³•çš„狀態值" @@ -300,7 +303,7 @@ msgstr "(點é¸æ¬²åˆªé™¤çš„æˆå“¡)" msgid "(Check box to delete scrip)" msgstr "(點é¸æ¬²åˆªé™¤çš„手續)" -#: html/Admin/Elements/EditCustomFieldValues:24 html/Admin/Elements/EditQueueWatchers:28 html/Admin/Elements/EditScrips:34 html/Admin/Elements/EditTemplates:35 html/Admin/Elements/EditWorkflows:36 html/Admin/Groups/Members.html:51 html/Ticket/Elements/EditLinks:32 html/Ticket/Elements/EditPeople:45 html/User/Groups/Members.html:54 +#: html/Admin/Elements/EditCustomFieldValues:24 html/Admin/Elements/EditQueueWatchers:28 html/Admin/Elements/EditScrips:34 html/Admin/Elements/EditTemplates:35 html/Admin/Elements/EditWorkflows:36 html/Admin/Groups/Members.html:51 html/Ticket/Elements/EditLinks:32 html/Ticket/Elements/EditPeople:45 html/User/Groups/Members.html:54 html/Work/Tickets/Elements/EditLinks:20 html/Work/Tickets/Elements/EditPeople:36 msgid "(Check box to delete)" msgstr "(點é¸æ¬²åˆªé™¤çš„é …ç›®)" @@ -308,7 +311,7 @@ msgstr "(點é¸æ¬²åˆªé™¤çš„é …ç›®)" msgid "(Check boxes to delete)" msgstr "(點é¸æ¬²åˆªé™¤çš„é …ç›®)" -#: html/Ticket/Create.html:177 +#: html/Ticket/Create.html:178 msgid "(Enter ticket ids or URLs, seperated with spaces)" msgstr "(éµå…¥ç”³è«‹å–®ç·¨è™Ÿæˆ–網å€ï¼Œä»¥ç©ºç™½åˆ†éš”)" @@ -342,7 +345,7 @@ msgstr "沒有範本" msgid "(No workflows)" msgstr "沒有æµç¨‹" -#: html/Ticket/Update.html:83 html/Work/Tickets/Update.html:52 +#: html/Ticket/Update.html:83 html/Work/Tickets/Update.html:56 msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)" msgstr "(é€å‡ºæœ¬ä»½æ›´æ–°çš„密件副本給å單上以逗號隔開的電å郵件ä½å€ã€‚這<b>ä¸æœƒ</b>更改後續的收件者å單。)" @@ -366,7 +369,7 @@ msgstr "(é€å‡ºæœ¬ä»½æ›´æ–°çš„副本給å單上以逗號隔開的電åéƒµä»¶ä½ msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)" msgstr "(é€å‡ºæœ¬ä»½æ›´æ–°çš„副本給å單上以逗號隔開的電å郵件ä½å€ã€‚這<b>將會</b>更改後續的收件者å單。)" -#: html/Ticket/Elements/EditCustomFieldEntries:35 html/Work/Tickets/Elements/EditCustomFieldEntries:48 html/Work/Tickets/Elements/ShowCustomFieldEntries:13 +#: html/Ticket/Elements/EditCustomFieldEntries:35 html/Work/Tickets/Elements/EditCustomFieldEntries:43 html/Work/Tickets/Elements/ShowCustomFieldEntries:14 msgid "(delete)" msgstr "(刪除)" @@ -374,7 +377,7 @@ msgstr "(刪除)" msgid "(empty)" msgstr "(空白)" -#: html/Edit/Global/CustomField/index.html:113 html/Edit/Global/Scrip/index.html:111 html/Edit/Global/Template/index.html:106 +#: html/Edit/Elements/Index:87 html/Edit/Global/CustomField/index.html:116 html/Edit/Global/Scrip/index.html:111 html/Edit/Global/Template/index.html:106 msgid "(new)" msgstr "(新增)" @@ -382,23 +385,23 @@ msgstr "(新增)" msgid "(no name listed)" msgstr "(沒有列出姓å)" -#: html/Elements/MyRequests:42 html/Elements/MyTickets:44 html/Work/Elements/MyApprovals:37 html/Work/Elements/MyRequests:42 html/Work/Elements/MyTickets:51 +#: html/Elements/MyRequests:42 html/Elements/MyTickets:44 html/Work/Elements/MyApprovals:37 html/Work/Elements/MyRequests:43 html/Work/Elements/MyTickets:52 msgid "(no subject)" msgstr "(沒有主題)" -#: html/Admin/Elements/SelectRights:47 html/Elements/SelectCustomFieldValue:29 html/Ticket/Elements/EditCustomField:60 html/Ticket/Elements/EditCustomFieldValues:52 html/Ticket/Elements/ShowCustomFields:35 html/Work/Elements/EditCustomFieldValues:50 html/Work/Elements/EditCustomFields:32 html/Work/Tickets/Elements/EditCustomFieldValues:33 lib/RT/Transaction_Overlay.pm:534 +#: html/Admin/Elements/SelectRights:47 html/Elements/SelectCustomFieldValue:29 html/Ticket/Elements/EditCustomField:64 html/Ticket/Elements/EditCustomFieldValues:52 html/Ticket/Elements/ShowCustomFields:35 html/Work/Elements/EditCustomFieldValues:50 html/Work/Elements/EditCustomFields:32 html/Work/Tickets/Elements/EditCustomFieldValues:33 lib/RT/Transaction_Overlay.pm:483 msgid "(no value)" msgstr "(ç„¡)" -#: html/Ticket/Elements/BulkLinks:27 html/Ticket/Elements/EditLinks:115 html/Work/Search/BulkLinks:3 +#: html/Ticket/Elements/BulkLinks:27 html/Ticket/Elements/EditLinks:98 html/Work/Search/BulkLinks:3 html/Work/Tickets/Elements/EditLinks:102 msgid "(only one ticket)" msgstr "(僅能指定一份申請單)" -#: html/Elements/MyRequests:51 html/Elements/MyTickets:54 html/Work/Elements/List:17 html/Work/Elements/MyRequests:52 html/Work/Elements/MyTickets:66 html/Work/Tickets/Elements/ShowBasics:52 +#: html/Elements/MyRequests:51 html/Elements/MyTickets:54 html/Work/Elements/List:17 html/Work/Elements/MyRequests:53 html/Work/Elements/MyTickets:67 html/Work/Tickets/Elements/ShowBasics:52 msgid "(pending approval)" msgstr "(ç‰å¾…ç°½æ ¸)" -#: html/Elements/MyRequests:53 html/Elements/MyTickets:56 html/Work/Elements/MyRequests:54 html/Work/Elements/MyTickets:68 +#: html/Elements/MyRequests:53 html/Elements/MyTickets:56 html/Work/Elements/MyRequests:55 html/Work/Elements/MyTickets:69 msgid "(pending other tickets)" msgstr "(ç‰å¾…其他申請單)" @@ -406,11 +409,11 @@ msgstr "(ç‰å¾…其他申請單)" msgid "(requestor's group)" msgstr "(申請人所屬)" -#: html/Admin/Users/Modify.html:49 +#: html/Admin/Users/Modify.html:49 html/Edit/Users/Info:26 msgid "(required)" msgstr "(å¿…å¡«)" -#: html/Ticket/Elements/ShowTransaction:92 html/Work/Tickets/Elements/ShowTransaction:39 +#: html/Ticket/Elements/ShowTransaction:103 html/Work/Tickets/Elements/ShowTransaction:44 msgid "(untitled)" msgstr "(未命å)" @@ -426,12 +429,12 @@ msgstr "<% $Ticket->Status%>" msgid "<% $_ %>" msgstr "<% $_ %>" -#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:25 html/Work/Elements/104Header:43 +#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:25 html/Work/Elements/104Header:43 lib/RT/StyleGuide.pod:767 #. ($m->scomp('/Elements/SelectNewTicketQueue')) msgid "<input type=\"submit\" value=\"New ticket in\"> %1" msgstr "<input type=\"submit\" value=\"æ出申請單\"> %1" -#: etc/initialdata.zh:221 etc/initialdata:203 +#: etc/initialdata:203 msgid "A blank template" msgstr "空白範本" @@ -479,11 +482,11 @@ msgstr "系統使用登錄權é™" msgid "Access control" msgstr "å˜å–權é™" -#: html/Admin/Elements/EditScrip:56 html/Work/Tickets/Elements/ShowTransaction:18 +#: html/Admin/Elements/EditScrip:56 html/Work/Tickets/Elements/ShowTransaction:21 msgid "Action" msgstr "動作" -#: lib/RT/Scrip_Overlay.pm:146 +#: lib/RT/Scrip_Overlay.pm:148 #. ($args{'ScripAction'}) msgid "Action %1 not found" msgstr "動作 %1 找ä¸åˆ°" @@ -496,11 +499,11 @@ msgstr "動作執行完畢" msgid "Action prepared..." msgstr "動作準備完畢..." -#: html/Work/Elements/List:13 html/Work/Elements/SelectSearch:24 html/Work/Tickets/Create.html:28 html/Work/Tickets/Elements/ShowBasics:12 +#: html/Work/Elements/List:13 html/Work/Elements/SelectSearch:25 html/Work/Tickets/Create.html:27 html/Work/Tickets/Elements/ShowBasics:12 msgid "Activated Date" msgstr "申請啟動時間" -#: html/Edit/Elements/104Buttons:71 html/Edit/Elements/ListButtons:7 +#: html/Edit/Elements/104Buttons:82 html/Edit/Elements/ListButtons:7 msgid "Add" msgstr "新增" @@ -512,11 +515,11 @@ msgstr "新增管ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" msgid "Add Cc" msgstr "新增副本收件人" -#: html/Ticket/Elements/EditCustomFieldEntries:71 html/Work/Tickets/Elements/ShowCustomFieldEntries:49 +#: html/Ticket/Elements/EditCustomFieldEntries:71 html/Work/Tickets/Elements/ShowCustomFieldEntries:50 msgid "Add Entry" msgstr "新增列" -#: html/Ticket/Create.html:113 html/Ticket/Update.html:98 html/Work/Tickets/Elements/AddAttachments:18 +#: html/Ticket/Create.html:113 html/Ticket/Update.html:98 html/Work/Tickets/Elements/AddAttachments:23 msgid "Add More Files" msgstr "新增更多附件" @@ -577,16 +580,20 @@ msgstr "æ–°å¢žä¸‹ä¸€é …é—œå¡" msgid "Added principal as a %1 for this queue" msgstr "å–®ä½å·²æ–°å¢žç‚ºæ¤è¡¨å–®çš„ %1" -#: lib/RT/Ticket_Overlay.pm:1453 +#: lib/RT/Ticket_Overlay.pm:1480 #. ($self->loc($args{'Type'})) msgid "Added principal as a %1 for this ticket" msgstr "å–®ä½å·²æ–°å¢žç‚ºæ¤ç”³è«‹å–®çš„ %1" -#: html/Admin/Elements/ModifyUser:75 html/Admin/Users/Modify.html:121 html/User/Prefs.html:87 html/Work/Preferences/Info:77 +#: html/Edit/Global/CustomField/Top:52 +msgid "Additional Hints" +msgstr "é¡å¤–æ示" + +#: html/Admin/Elements/ModifyUser:75 html/Admin/Users/Modify.html:121 html/User/Prefs.html:114 html/Work/Preferences/Info:79 msgid "Address1" msgstr "ä½å€" -#: html/Admin/Elements/ModifyUser:77 html/Admin/Users/Modify.html:126 html/User/Prefs.html:89 html/Work/Preferences/Info:79 +#: html/Admin/Elements/ModifyUser:77 html/Admin/Users/Modify.html:126 html/User/Prefs.html:118 html/Work/Preferences/Info:81 msgid "Address2" msgstr "ä½å€(續)" @@ -594,7 +601,7 @@ msgstr "ä½å€(續)" msgid "Adjust Blinking Rate" msgstr "調整閃çˆé€Ÿåº¦å¿«æ…¢" -#: html/Edit/Groups/Admin:9 +#: html/Edit/Queues/List:12 msgid "Admin" msgstr "管ç†å“¡" @@ -602,11 +609,11 @@ msgstr "管ç†å“¡" msgid "Admin Cc" msgstr "管ç†å“¡å‰¯æœ¬" -#: etc/initialdata.zh:303 etc/initialdata:280 +#: etc/initialdata:280 msgid "Admin Comment" msgstr "管ç†å“¡è©•è«–" -#: etc/initialdata.zh:261 etc/initialdata:259 +#: etc/initialdata:259 msgid "Admin Correspondence" msgstr "管ç†å“¡å›žè¦†" @@ -634,7 +641,7 @@ msgstr "管ç†/群組" msgid "Admin/Queue/Basics" msgstr "管ç†/表單/基本資訊" -#: html/Edit/Global/Basic/Top:60 +#: html/Edit/Global/Basic/Top:65 msgid "AdminAddress" msgstr "管ç†å“¡ Email" @@ -642,7 +649,7 @@ msgstr "管ç†å“¡ Email" msgid "AdminAllPersonalGroups" msgstr "管ç†æ‰€æœ‰ä»£ç†äººç¾¤çµ„" -#: etc/initialdata.zh:74 etc/initialdata:56 html/Admin/Elements/ModifyTemplateAsWorkflow:155 html/Ticket/Elements/ShowPeople:38 html/Ticket/Update.html:49 lib/RT/ACE_Overlay.pm:88 +#: etc/initialdata:56 html/Admin/Elements/ModifyTemplateAsWorkflow:155 html/Ticket/Elements/ShowPeople:38 html/Ticket/Update.html:49 html/Work/Tickets/Elements/ShowLinks:11 lib/RT/ACE_Overlay.pm:88 msgid "AdminCc" msgstr "管ç†å“¡å‰¯æœ¬" @@ -658,7 +665,7 @@ msgstr "管ç†å“¡å›žè¦†" msgid "AdminCustomFields" msgstr "管ç†è‡ªè¨‚欄ä½" -#: html/Edit/Groups/Admin:12 lib/RT/Group_Overlay.pm:145 +#: lib/RT/Group_Overlay.pm:145 msgid "AdminGroup" msgstr "管ç†ç¾¤çµ„" @@ -698,7 +705,7 @@ msgstr "管ç†ä½¿ç”¨è€…" msgid "Administrative" msgstr "行政類" -#: html/Admin/Queues/People.html:47 html/Ticket/Elements/EditPeople:53 +#: html/Admin/Queues/People.html:47 html/Ticket/Elements/EditPeople:53 html/Work/Tickets/Elements/EditPeople:44 msgid "Administrative Cc" msgstr "管ç†å“¡å‰¯æœ¬" @@ -718,7 +725,7 @@ msgstr "晚於" msgid "Age" msgstr "經æ·æ™‚é–“" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:172 html/Edit/Global/Workflow/Action:39 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:172 html/Edit/Global/Workflow/Action:35 msgid "Alias" msgstr "執行其他æµç¨‹" @@ -726,11 +733,11 @@ msgstr "執行其他æµç¨‹" msgid "Alias for" msgstr "相當於" -#: html/Edit/Queues/index.html:33 html/Work/Delegates/index.html:13 html/Work/Elements/SelectSearch:11 html/Work/Queues/Select.html:14 html/Work/Queues/index.html:13 +#: html/Work/Delegates/index.html:13 html/Work/Elements/SelectSearch:11 html/Work/Queues/Select.html:14 html/Work/Queues/index.html:13 msgid "All" msgstr "全部" -#: etc/initialdata.zh:372 etc/initialdata:348 +#: etc/initialdata:348 msgid "All Approvals Passed" msgstr "完æˆå…¨éƒ¨ç°½æ ¸" @@ -738,7 +745,7 @@ msgstr "完æˆå…¨éƒ¨ç°½æ ¸" msgid "All Condition" msgstr "所有æ¢ä»¶" -#: html/Admin/Elements/EditCustomFields:95 +#: html/Admin/Elements/EditCustomFields:94 msgid "All Custom Fields" msgstr "所有自訂欄ä½" @@ -751,6 +758,10 @@ msgid "All Users" msgstr "全體員工" #: NOT FOUND IN SOURCE +msgid "All done! Now you can proceed to %1." +msgstr "處ç†å®Œç•¢ï¼æ‚¨ç¾åœ¨å¯ä»¥ç¹¼çºŒé€²è¡Œ %1。" + +#: NOT FOUND IN SOURCE msgid "Allowance Request" msgstr "ç¦åˆ©è£œåŠ©ç”³è«‹" @@ -766,7 +777,7 @@ msgstr "數é¡" msgid "Any Condition" msgstr "ä»»æ„æ¢ä»¶" -#: html/Edit/Global/Scrip/List:10 html/Edit/Global/Scrip/Top:74 +#: html/Edit/Global/Scrip/List:10 html/Edit/Global/Scrip/Top:86 msgid "Apply Template" msgstr "引用範本" @@ -803,11 +814,11 @@ msgstr "ç°½æ ¸æ™‚é™" msgid "Approval Notes" msgstr "ç°½æ ¸æ„見" -#: etc/initialdata.zh:357 etc/initialdata:336 +#: etc/initialdata:336 msgid "Approval Passed" msgstr "完æˆæŸé …ç°½æ ¸" -#: etc/initialdata.zh:383 etc/initialdata:359 +#: etc/initialdata:359 msgid "Approval Rejected" msgstr "é§å›žæŸé …ç°½æ ¸" @@ -835,11 +846,11 @@ msgstr "æ ¸å‡†" msgid "Approver" msgstr "ç°½æ ¸äºº" -#: html/Edit/Global/Workflow/Action:29 html/Edit/Global/Workflow/Owner.html:10 +#: html/Edit/Global/Workflow/Action:25 html/Edit/Global/Workflow/Owner.html:10 msgid "Approver Setting" msgstr "åŸ·è¡Œç°½æ ¸äººè¨å®š" -#: etc/initialdata.zh:516 etc/initialdata:486 etc/upgrade/2.1.71:148 html/Edit/Elements/CreateApprovalsQueue:122 +#: etc/initialdata:486 etc/upgrade/2.1.71:148 html/Edit/Elements/CreateApprovalsQueue:122 msgid "Approver's notes: %1" msgstr "ç°½æ ¸å‚™è¨»ï¼š%1" @@ -863,15 +874,15 @@ msgstr "您確定è¦åˆªé™¤ï¼Ÿ" msgid "Ascending" msgstr "éžå¢ž" -#: html/Search/Bulk.html:136 html/SelfService/Update.html:32 html/Ticket/ModifyAll.html:82 html/Ticket/Update.html:98 html/Work/Search/Bulk.html:88 +#: html/Search/Bulk.html:136 html/SelfService/Update.html:47 html/Ticket/ModifyAll.html:82 html/Ticket/Update.html:98 html/Work/Search/Bulk.html:88 msgid "Attach" msgstr "附件" -#: html/SelfService/Create.html:64 html/Ticket/Create.html:109 html/Work/Tickets/Elements/AddAttachments:15 +#: html/SelfService/Create.html:64 html/Ticket/Create.html:109 html/Work/Tickets/Elements/AddAttachments:19 msgid "Attach file" msgstr "é™„åŠ æª”æ¡ˆ" -#: html/Ticket/Create.html:97 html/Ticket/Update.html:87 html/Work/Tickets/Elements/AddAttachments:6 +#: html/SelfService/Update.html:36 html/Ticket/Create.html:97 html/Ticket/Update.html:87 html/Work/Tickets/Elements/AddAttachments:7 html/Work/Tickets/Elements/ShowAttachments:9 msgid "Attached file" msgstr "ç¾æœ‰é™„件" @@ -879,15 +890,15 @@ msgstr "ç¾æœ‰é™„件" msgid "Attachment '%1' could not be loaded" msgstr "無法載入附件 '%1'" -#: lib/RT/Transaction_Overlay.pm:441 +#: lib/RT/Transaction_Overlay.pm:390 lib/RT/Transaction_Vendor.pm:50 msgid "Attachment created" msgstr "附件新增完畢" -#: lib/RT/Tickets_Overlay.pm:1189 +#: lib/RT/Tickets_Overlay.pm:1208 msgid "Attachment filename" msgstr "附件檔å" -#: html/Ticket/Elements/ShowAttachments:25 html/Work/Tickets/Elements/ShowTransaction:32 +#: html/Ticket/Elements/ShowAttachments:25 html/Work/Tickets/Elements/ShowTransaction:37 msgid "Attachments" msgstr "附件" @@ -915,11 +926,11 @@ msgstr "自動é§å›žè¡¨å–®" msgid "AutoResolve" msgstr "自動完æˆè¡¨å–®è™•ç†" -#: etc/initialdata.zh:224 etc/initialdata:206 +#: etc/initialdata:206 msgid "Autoreply" msgstr "自動回覆" -#: etc/initialdata.zh:90 etc/initialdata:72 +#: etc/initialdata:72 msgid "Autoreply To Requestors" msgstr "自動å°ç”³è«‹äººå›žè¦†" @@ -927,7 +938,7 @@ msgstr "自動å°ç”³è«‹äººå›žè¦†" msgid "AutoreplyToRequestors" msgstr "自動å°ç”³è«‹äººå›žè¦†" -#: html/Edit/Rights/index.html:16 +#: html/Edit/Rights/index.html:17 msgid "Available Rights:" msgstr "權é™é …目列表:" @@ -956,19 +967,19 @@ msgstr "%1 的資料錯誤" msgid "Bad transaction number for attachment. %1 should be %2\\n" msgstr "附件的處ç†è™Ÿç¢¼éŒ¯èª¤ã€‚%1 應為 %2\\n" -#: html/Admin/Elements/GroupTabs:38 html/Admin/Elements/QueueTabs:38 html/Admin/Elements/UserTabs:37 html/Edit/Global/autohandler:6 html/Edit/Queues/autohandler:17 html/Edit/Users/index.html:121 html/Ticket/Elements/Tabs:89 html/User/Elements/GroupTabs:37 +#: html/Admin/Elements/GroupTabs:38 html/Admin/Elements/QueueTabs:38 html/Admin/Elements/UserTabs:37 html/Edit/Global/autohandler:6 html/Edit/Queues/autohandler:21 html/Edit/Users/index.html:94 html/Ticket/Elements/Tabs:89 html/User/Elements/GroupTabs:37 msgid "Basics" msgstr "基本資訊" -#: html/Ticket/Update.html:81 html/Work/Tickets/Update.html:49 +#: html/Ticket/Update.html:81 html/Work/Tickets/Update.html:53 msgid "Bcc" msgstr "密件副本" -#: html/Admin/Elements/EditScrip:87 html/Admin/Global/GroupRights.html:84 html/Admin/Global/Template.html:45 html/Admin/Global/UserRights.html:53 html/Admin/Global/Workflow.html:46 html/Admin/Groups/GroupRights.html:72 html/Admin/Groups/Members.html:80 html/Admin/Groups/Modify.html:55 html/Admin/Groups/UserRights.html:54 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:44 html/Admin/Queues/UserRights.html:53 html/Admin/Queues/Workflow.html:44 html/User/Groups/Modify.html:55 +#: html/Admin/Elements/EditScrip:95 html/Admin/Global/GroupRights.html:84 html/Admin/Global/Template.html:45 html/Admin/Global/UserRights.html:53 html/Admin/Global/Workflow.html:46 html/Admin/Groups/GroupRights.html:72 html/Admin/Groups/Members.html:80 html/Admin/Groups/Modify.html:55 html/Admin/Groups/UserRights.html:54 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:44 html/Admin/Queues/UserRights.html:53 html/Admin/Queues/Workflow.html:44 html/User/Groups/Modify.html:55 msgid "Be sure to save your changes" msgstr "請別忘了儲å˜ä¿®æ”¹ã€‚" -#: html/Elements/SelectDateRelation:33 lib/RT/CurrentUser.pm:321 +#: html/Elements/SelectDateRelation:33 lib/RT/CurrentUser.pm:320 msgid "Before" msgstr "æ—©æ–¼" @@ -980,11 +991,11 @@ msgstr "é–‹å§‹ç°½æ ¸" msgid "Begin From " msgstr "起始日" -#: html/Edit/Users/Info:25 +#: NOT FOUND IN SOURCE msgid "Birthday" msgstr "生日" -#: etc/initialdata.zh:220 etc/initialdata:202 +#: etc/initialdata:202 msgid "Blank" msgstr "空白範本" @@ -1008,7 +1019,7 @@ msgstr "事æ¥éƒ¨" msgid "Business Unit:" msgstr "事æ¥éƒ¨ï¼š" -#: lib/RT/User_Overlay.pm:1524 +#: lib/RT/User_Overlay.pm:1529 msgid "Can not modify system users" msgstr "無法更改系統使用者" @@ -1024,11 +1035,11 @@ msgstr "ä¸èƒ½æ–°å¢žæ²’有å稱的自訂欄ä½å€¼" msgid "Can't link a ticket to itself" msgstr "申請單ä¸èƒ½éˆçµè‡ªå·±ã€‚" -#: lib/RT/Ticket_Overlay.pm:2807 +#: lib/RT/Ticket_Overlay.pm:2857 msgid "Can't merge into a merged ticket. You should never get this error" msgstr "ä¸èƒ½æ•´åˆé€²å·²æ•´åˆéŽçš„申請單。這個錯誤ä¸è©²ç™¼ç”Ÿã€‚" -#: lib/RT/Ticket_Overlay.pm:2625 lib/RT/Ticket_Overlay.pm:2694 +#: lib/RT/Ticket_Overlay.pm:2659 lib/RT/Ticket_Overlay.pm:2738 msgid "Can't specifiy both base and target" msgstr "ä¸èƒ½åŒæ™‚指定起始申請單與目的申請單" @@ -1036,7 +1047,7 @@ msgstr "ä¸èƒ½åŒæ™‚指定起始申請單與目的申請單" msgid "Cancel" msgstr "å–消" -#: html/autohandler:113 +#: html/autohandler:126 #. ($msg) msgid "Cannot create user: %1" msgstr "無法新增使用者:%1" @@ -1053,7 +1064,7 @@ msgstr "分類管ç†" msgid "Category" msgstr "分類" -#: etc/initialdata.zh:68 etc/initialdata:50 html/Admin/Queues/People.html:43 html/SelfService/Create.html:48 html/Ticket/Create.html:63 html/Ticket/Elements/EditPeople:50 html/Ticket/Elements/ShowPeople:34 html/Ticket/Update.html:44 html/Ticket/Update.html:76 html/Work/Tickets/Update.html:43 lib/RT/ACE_Overlay.pm:87 +#: etc/initialdata:50 html/Admin/Queues/People.html:43 html/SelfService/Create.html:48 html/Ticket/Create.html:63 html/Ticket/Elements/EditPeople:50 html/Ticket/Elements/ShowPeople:34 html/Ticket/Update.html:44 html/Ticket/Update.html:76 html/Work/Tickets/Elements/EditPeople:41 html/Work/Tickets/Elements/ShowLinks:6 html/Work/Tickets/Update.html:43 lib/RT/ACE_Overlay.pm:87 msgid "Cc" msgstr "副本" @@ -1073,11 +1084,11 @@ msgstr "修改申請單" msgid "Change password" msgstr "更改密碼" -#: html/Edit/Global/Basic/Top:70 +#: html/Edit/Global/Basic/Top:79 msgid "ChangeOwnerUI" msgstr "å¯å¦é¸æ“‡è¡¨å–®æ‰¿è¾¦äºº" -#: html/Ticket/Create.html:100 html/Ticket/Elements/EditCustomFieldEntries:35 html/Ticket/Update.html:90 html/Work/Tickets/Elements/ShowCustomFieldEntries:13 +#: html/SelfService/Update.html:39 html/Ticket/Create.html:100 html/Ticket/Elements/EditCustomFieldEntries:35 html/Ticket/Update.html:90 html/Work/Tickets/Elements/ShowCustomFieldEntries:14 msgid "Check box to delete" msgstr "é¸æ“‡æ¬²åˆªé™¤çš„é …ç›®" @@ -1085,11 +1096,11 @@ msgstr "é¸æ“‡æ¬²åˆªé™¤çš„é …ç›®" msgid "Check box to revoke right" msgstr "é¸æ“‡æ¬²æ’¤æ¶ˆçš„權利" -#: html/Ticket/Create.html:182 html/Ticket/Elements/BulkLinks:42 html/Ticket/Elements/EditLinks:130 html/Ticket/Elements/EditLinks:68 html/Ticket/Elements/ShowLinks:56 html/Work/Search/BulkLinks:18 +#: html/Ticket/Create.html:183 html/Ticket/Elements/BulkLinks:42 html/Ticket/Elements/EditLinks:113 html/Ticket/Elements/EditLinks:63 html/Ticket/Elements/ShowLinks:56 html/Work/Search/BulkLinks:18 html/Work/Tickets/Elements/EditLinks:117 html/Work/Tickets/Elements/EditLinks:56 html/Work/Tickets/Elements/ShowMembers:4 msgid "Children" msgstr "å申請單" -#: html/Edit/Elements/PickUsers:21 html/Edit/Global/UserRight/List:8 html/Edit/Global/UserRight/Top:19 html/Edit/Users/List:6 html/Edit/Users/Top:18 +#: html/Edit/Elements/PickUsers:21 html/Edit/Global/UserRight/List:8 html/Edit/Global/UserRight/Top:19 msgid "Chinese Name" msgstr "ä¸æ–‡å§“å" @@ -1097,7 +1108,7 @@ msgstr "ä¸æ–‡å§“å" msgid "Chinese/English" msgstr "ä¸è‹±æ–‡" -#: html/Admin/Elements/ModifyUser:79 html/Admin/Users/Modify.html:131 html/User/Prefs.html:91 html/Work/Preferences/Info:81 +#: html/Admin/Elements/ModifyUser:79 html/Admin/Users/Modify.html:131 html/User/Prefs.html:122 html/Work/Preferences/Info:83 msgid "City" msgstr "所在城市" @@ -1105,7 +1116,7 @@ msgstr "所在城市" msgid "ClassicUI" msgstr "傳統介é¢" -#: html/Ticket/Elements/ShowDates:46 +#: html/Ticket/Elements/ShowDates:47 msgid "Closed" msgstr "已解決" @@ -1117,7 +1128,7 @@ msgstr "已解決的申請單" msgid "Closed tickets" msgstr "已解決的申請單" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:181 html/Edit/Global/Workflow/Action:58 html/Edit/Global/Workflow/Condition:51 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:181 html/Edit/Global/Workflow/Action:54 html/Edit/Global/Workflow/Condition:52 msgid "Code" msgstr "執行程å¼ç¢¼" @@ -1125,7 +1136,7 @@ msgstr "執行程å¼ç¢¼" msgid "Command not understood!\\n" msgstr "指令無法辨è˜ï¼\\n" -#: html/Ticket/Elements/ShowTransaction:166 html/Ticket/Elements/Tabs:152 html/Work/Search/Bulk.html:89 html/Work/Tickets/Display.html:37 html/Work/Tickets/Elements/ShowTransaction:114 html/Work/Tickets/Elements/ShowTransaction:27 +#: html/Ticket/Elements/ShowTransaction:178 html/Ticket/Elements/Tabs:152 html/Work/Search/Bulk.html:89 html/Work/Tickets/Display.html:60 html/Work/Tickets/Elements/ShowTransaction:118 html/Work/Tickets/Elements/ShowTransaction:32 msgid "Comment" msgstr "è©•è«–" @@ -1145,7 +1156,7 @@ msgstr "å°ç”³è«‹å–®æ出評論" msgid "CommentOnTicket" msgstr "評論申請單" -#: html/Admin/Elements/ModifyUser:34 html/Work/Tickets/Update.html:59 +#: html/Admin/Elements/ModifyUser:34 html/Work/Tickets/Elements/AddContent:7 msgid "Comments" msgstr "è©•è«–" @@ -1162,11 +1173,11 @@ msgstr "è©•è«–(ä¸é€çµ¦ç”³è«‹äºº)" msgid "Comments about %1" msgstr "å° %1 çš„è©•è«–" -#: html/Admin/Users/Modify.html:184 html/Ticket/Elements/ShowRequestor:43 +#: html/Admin/Users/Modify.html:184 html/Edit/Users/Info:46 html/Ticket/Elements/ShowRequestor:43 msgid "Comments about this user" msgstr "使用者æè¿°" -#: lib/RT/Transaction_Overlay.pm:543 +#: lib/RT/Transaction_Overlay.pm:501 msgid "Comments added" msgstr "新增評論完畢" @@ -1178,10 +1189,14 @@ msgstr "確èª" msgid "Commit Stubbed" msgstr "消除更動完畢" -#: html/Edit/Users/Info:41 +#: NOT FOUND IN SOURCE msgid "Company Name" msgstr "å…¬å¸å稱" +#: html/Edit/Global/Basic/Top:85 +msgid "CompanySpecific" +msgstr "å„å…¬å¸ç¨ç«‹é¡¯ç¤º" + #: NOT FOUND IN SOURCE msgid "Compile Restrictions" msgstr "è¨å®šæŸ¥è©¢æ¢ä»¶" @@ -1194,11 +1209,11 @@ msgstr "æ¢ä»¶" msgid "Condition matches..." msgstr "符åˆæ¢ä»¶..." -#: lib/RT/Scrip_Overlay.pm:159 +#: lib/RT/Scrip_Overlay.pm:164 msgid "Condition not found" msgstr "未找到符åˆçš„ç¾æ³" -#: html/Edit/Global/GroupRight/Top:26 html/Edit/Global/UserRight/Top:45 html/Edit/Groups/Member:57 html/Elements/Tabs:49 +#: html/Edit/Global/GroupRight/Top:26 html/Edit/Global/UserRight/Top:45 html/Edit/Groups/Member:56 html/Elements/Tabs:49 msgid "Configuration" msgstr "è¨å®š" @@ -1210,7 +1225,7 @@ msgstr "確èªå¯†ç¢¼" msgid "Confirm Password" msgstr "密碼確èª" -#: html/Work/Approvals/Display.html:25 html/Work/Tickets/Create.html:161 html/Work/Tickets/Create.html:174 html/Work/Tickets/Update.html:81 +#: html/Work/Approvals/Display.html:25 html/Work/Tickets/Create.html:154 html/Work/Tickets/Create.html:168 html/Work/Tickets/Update.html:77 msgid "Confirm Submit" msgstr "確定é€å‡º" @@ -1234,7 +1249,7 @@ msgstr "內容" msgid "Coould not create group" msgstr "無法新增群組" -#: html/Edit/Elements/104Buttons:74 +#: html/Edit/Elements/104Buttons:85 msgid "Copy" msgstr "複製" @@ -1242,7 +1257,7 @@ msgstr "複製" msgid "Copy Field From:" msgstr "欲複製欄ä½ï¼š" -#: etc/initialdata.zh:282 etc/initialdata:271 +#: etc/initialdata:271 msgid "Correspondence" msgstr "回覆" @@ -1250,7 +1265,7 @@ msgstr "回覆" msgid "Correspondence Address" msgstr "申請單回覆地å€" -#: lib/RT/Transaction_Overlay.pm:539 +#: lib/RT/Transaction_Overlay.pm:497 msgid "Correspondence added" msgstr "新增申請單回覆" @@ -1258,7 +1273,7 @@ msgstr "新增申請單回覆" msgid "Correspondence not recorded" msgstr "未紀錄申請單回覆" -#: lib/RT/Ticket_Overlay.pm:3552 +#: lib/RT/Ticket_Overlay.pm:3608 msgid "Could not add new custom field value for ticket. " msgstr "ä¸èƒ½æ–°å¢žè‡ªè¨‚欄ä½çš„值 " @@ -1266,11 +1281,11 @@ msgstr "ä¸èƒ½æ–°å¢žè‡ªè¨‚欄ä½çš„值 " msgid "Could not add new custom field value for ticket. %1 " msgstr "ä¸èƒ½æ–°å¢žè‡ªè¨‚欄ä½çš„值。%1 " -#: lib/RT/Ticket_Overlay.pm:3058 lib/RT/Ticket_Overlay.pm:3066 lib/RT/Ticket_Overlay.pm:3083 +#: lib/RT/Ticket_Overlay.pm:3108 lib/RT/Ticket_Overlay.pm:3116 lib/RT/Ticket_Overlay.pm:3133 msgid "Could not change owner. " msgstr "ä¸èƒ½æ›´æ”¹æ‰¿è¾¦äººã€‚ " -#: html/Admin/Elements/EditCustomField:84 html/Admin/Elements/EditCustomFields:165 html/Edit/Global/CustomField/index.html:117 +#: html/Admin/Elements/EditCustomField:84 html/Admin/Elements/EditCustomFields:164 html/Edit/Global/CustomField/index.html:120 #. ($msg) msgid "Could not create CustomField" msgstr "無法新增自訂欄ä½" @@ -1285,20 +1300,25 @@ msgstr "無法建立訊æ¯é€šçŸ¥" msgid "Could not create Template" msgstr "無法建立通知範本" -#: html/User/Groups/Modify.html:76 lib/RT/Group_Overlay.pm:473 lib/RT/Group_Overlay.pm:480 +#: html/User/Groups/Modify.html:76 lib/RT/Group_Overlay.pm:471 lib/RT/Group_Overlay.pm:478 msgid "Could not create group" msgstr "無法新增群組" +#: html/Edit/Elements/Index:89 +#. ($msg) +msgid "Could not create item" +msgstr "ç„¡æ³•æ–°å¢žé …ç›®" + #: html/Admin/Global/Template.html:74 html/Admin/Queues/Template.html:71 #. ($msg) msgid "Could not create template: %1" msgstr "無法新增範本:%1" -#: lib/RT/Ticket_Overlay.pm:1091 lib/RT/Ticket_Overlay.pm:334 +#: lib/RT/Ticket_Overlay.pm:1118 lib/RT/Ticket_Overlay.pm:353 msgid "Could not create ticket. Queue not set" msgstr "無法新增申請單。尚未指定表單。" -#: lib/RT/User_Overlay.pm:267 lib/RT/User_Overlay.pm:279 lib/RT/User_Overlay.pm:297 lib/RT/User_Overlay.pm:483 +#: lib/RT/User_Overlay.pm:271 lib/RT/User_Overlay.pm:284 lib/RT/User_Overlay.pm:302 lib/RT/User_Overlay.pm:488 msgid "Could not create user" msgstr "無法新增使用者" @@ -1319,11 +1339,11 @@ msgstr "找ä¸åˆ°ç·¨è™Ÿ %1 的申請單" msgid "Could not find group %1." msgstr "找ä¸åˆ°ç¾¤çµ„ %1。" -#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1421 +#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1448 msgid "Could not find or create that user" msgstr "找ä¸åˆ°æˆ–無法新增該å使用者" -#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1500 +#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1527 msgid "Could not find that principal" msgstr "找ä¸åˆ°è©²å–®ä½" @@ -1331,8 +1351,7 @@ msgstr "找ä¸åˆ°è©²å–®ä½" msgid "Could not find user %1." msgstr "找ä¸åˆ°ä½¿ç”¨è€… %1。" -#: html/Admin/Groups/Members.html:87 html/Edit/Users/index.html:83 html/User/Groups/Members.html:89 html/User/Groups/Modify.html:81 -#. ( . $GroupId) +#: html/Admin/Groups/Members.html:87 html/User/Groups/Members.html:89 html/User/Groups/Modify.html:81 msgid "Could not load group" msgstr "無法載入群組" @@ -1341,7 +1360,7 @@ msgstr "無法載入群組" msgid "Could not make that principal a %1 for this queue" msgstr "無法將該單ä½è¨ç‚ºæ¤è¡¨å–®çš„ %1。" -#: lib/RT/Ticket_Overlay.pm:1442 +#: lib/RT/Ticket_Overlay.pm:1469 #. ($self->loc($args{'Type'})) msgid "Could not make that principal a %1 for this ticket" msgstr "無法將該單ä½è¨ç‚ºæ¤ç”³è«‹å–®çš„ %1。" @@ -1351,16 +1370,16 @@ msgstr "無法將該單ä½è¨ç‚ºæ¤ç”³è«‹å–®çš„ %1。" msgid "Could not remove that principal as a %1 for this queue" msgstr "ç„¡æ³•å°‡å–®ä½ %1 從表單移除。" -#: lib/RT/Ticket_Overlay.pm:1558 +#: lib/RT/Ticket_Overlay.pm:1585 #. ($args{'Type'}) msgid "Could not remove that principal as a %1 for this ticket" msgstr "ç„¡æ³•å°‡å–®ä½ %1 從申請單移除。" -#: lib/RT/Group_Overlay.pm:984 +#: lib/RT/Group_Overlay.pm:982 msgid "Couldn't add member to group" msgstr "無法新增æˆå“¡è‡³ç¾¤çµ„" -#: lib/RT/Ticket_Overlay.pm:3562 lib/RT/Ticket_Overlay.pm:3618 +#: lib/RT/Ticket_Overlay.pm:3618 lib/RT/Ticket_Overlay.pm:3674 #. ($Msg) msgid "Couldn't create a transaction: %1" msgstr "ç„¡æ³•æ–°å¢žæ›´å‹•å ±å‘Š" @@ -1373,11 +1392,11 @@ msgstr "無法從 gpg 回函辨è˜å‡ºè©²æŽ¡å–的行動\\n" msgid "Couldn't find group\\n" msgstr "找ä¸åˆ°ç¾¤çµ„\\n" -#: lib/RT/Interface/Web.pm:902 x:905 +#: lib/RT/Interface/Web.pm:962 msgid "Couldn't find row" msgstr "找ä¸åˆ°æ¤åˆ—資料" -#: lib/RT/Group_Overlay.pm:958 +#: lib/RT/Group_Overlay.pm:956 msgid "Couldn't find that principal" msgstr "找ä¸åˆ°è©²å–®ä½" @@ -1410,9 +1429,10 @@ msgstr "無法載入 RT è¨å®šæª” '%1' %2" msgid "Couldn't load Scrips." msgstr "無法載入手續。" -#: html/Admin/Groups/GroupRights.html:87 html/Admin/Groups/UserRights.html:74 html/Edit/Global/GroupRight/Add.html:54 html/Edit/Global/UserRight/Add.html:23 html/Edit/Groups/Member:121 html/Edit/Groups/Members/Add.html:44 html/Edit/Rights/index.html:57 -#. ($Group) +#: html/Admin/Groups/GroupRights.html:87 html/Admin/Groups/UserRights.html:74 html/Edit/Global/GroupRight/Add.html:55 html/Edit/Global/GroupRight/Add.html:60 html/Edit/Global/UserRight/Add.html:25 html/Edit/Global/UserRight/Add.html:30 html/Edit/Groups/Member:120 html/Edit/Groups/Members/Add.html:43 html/Edit/Rights/index.html:58 html/Edit/Rights/index.html:63 #. ($ObjectGroup) +#. ($Report) +#. ($Group) #. ($id) msgid "Couldn't load group %1" msgstr "無法載入手續 %1" @@ -1421,12 +1441,12 @@ msgstr "無法載入手續 %1" msgid "Couldn't load link" msgstr "無法載入éˆçµã€‚" -#: html/Admin/Elements/EditCustomFields:146 html/Admin/Queues/People.html:120 +#: html/Admin/Elements/EditCustomFields:145 html/Admin/Queues/CustomFields.html:35 html/Admin/Queues/People.html:120 #. ($id) msgid "Couldn't load queue" msgstr "無法載入表單" -#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:71 html/Edit/Global/GroupRight/Add.html:50 html/Edit/Global/GroupRight/index.html:81 html/Edit/Global/UserRight/Add.html:19 html/Edit/Global/UserRight/index.html:83 html/Edit/Rights/index.html:53 +#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:71 html/Edit/Global/GroupRight/Add.html:51 html/Edit/Global/GroupRight/index.html:82 html/Edit/Global/GroupRight/index.html:87 html/Edit/Global/UserRight/Add.html:21 html/Edit/Global/UserRight/index.html:83 html/Edit/Global/UserRight/index.html:88 html/Edit/Rights/index.html:54 #. ($Queue) #. ($id) msgid "Couldn't load queue %1" @@ -1445,16 +1465,16 @@ msgstr "無法載入範本" msgid "Couldn't load that user (%1)" msgstr "無法載入該å使用者(%1)" -#: html/SelfService/Display.html:108 +#: html/SelfService/Display.html:114 #. ($id) msgid "Couldn't load ticket '%1'" msgstr "無法載入申請單 '%1'" -#: html/Admin/Elements/ModifyUser:85 html/Admin/Users/Modify.html:148 html/User/Prefs.html:97 html/Work/Preferences/Info:87 +#: html/Admin/Elements/ModifyUser:85 html/Admin/Users/Modify.html:148 html/User/Prefs.html:134 html/Work/Preferences/Info:89 msgid "Country" msgstr "國家" -#: html/Admin/Elements/CreateUserCalled:25 html/Edit/Elements/PopHeader:29 html/Edit/Global/GroupRight/Add.html:18 html/Ticket/Create.html:134 html/Ticket/Create.html:194 +#: html/Admin/Elements/CreateUserCalled:25 html/Edit/Elements/PopHeader:33 html/Edit/Global/GroupRight/Add.html:19 html/Ticket/Create.html:134 html/Ticket/Create.html:195 msgid "Create" msgstr "新增" @@ -1462,7 +1482,7 @@ msgstr "新增" msgid "Create Subgroup:" msgstr "新增å群組:" -#: etc/initialdata.zh:145 etc/initialdata:127 +#: etc/initialdata:127 msgid "Create Tickets" msgstr "新增申請單" @@ -1519,7 +1539,7 @@ msgstr "新增範本" msgid "Create a new ticket" msgstr "新增申請單" -#: html/Admin/Users/Modify.html:213 html/Admin/Users/Modify.html:240 +#: html/Admin/Users/Modify.html:213 html/Admin/Users/Modify.html:242 msgid "Create a new user" msgstr "新增使用者" @@ -1568,7 +1588,7 @@ msgstr "新增失敗:%1/%2/%3" msgid "Create new item" msgstr "å»ºç«‹æ–°é …ç›®" -#: etc/initialdata.zh:147 etc/initialdata:129 +#: etc/initialdata:129 msgid "Create new tickets based on this scrip's template" msgstr "ä¾æ“šæ¤é …手續內的模版,新增申請單" @@ -1604,7 +1624,7 @@ msgstr "新增ã€åˆªé™¤åŠæ›´æ”¹ä½¿ç”¨è€…" msgid "CreateTicket" msgstr "新增申請單" -#: html/Elements/SelectDateType:25 html/Ticket/Elements/ShowDates:26 lib/RT/Ticket_Overlay.pm:1185 +#: html/Elements/SelectDateType:25 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1212 msgid "Created" msgstr "新增日" @@ -1638,11 +1658,11 @@ msgstr "ç¾æœ‰è‡ªè¨‚欄ä½" msgid "Current Groups:" msgstr "ç¾æœ‰ç¾¤çµ„列表:" -#: html/Ticket/Elements/EditLinks:27 +#: html/Ticket/Elements/EditLinks:27 html/Work/Tickets/Elements/EditLinks:10 msgid "Current Relationships" msgstr "ç¾æœ‰é—œä¿‚" -#: html/Edit/Rights/index.html:19 +#: html/Edit/Rights/index.html:20 msgid "Current Rights:" msgstr "ç¾æœ‰æ¬Šé™ï¼š" @@ -1650,7 +1670,7 @@ msgstr "ç¾æœ‰æ¬Šé™ï¼š" msgid "Current Scrips" msgstr "ç¾æœ‰æ‰‹çºŒ" -#: html/Work/Tickets/Create.html:50 html/Work/Tickets/Elements/ShowBasics:47 +#: html/Work/Tickets/Create.html:49 html/Work/Tickets/Elements/ShowBasics:47 msgid "Current Status" msgstr "ç›®å‰ç‹€æ…‹" @@ -1658,6 +1678,10 @@ msgstr "ç›®å‰ç‹€æ…‹" msgid "Current Templates" msgstr "ç¾æœ‰ç¯„本" +#: html/Work/Tickets/Elements/EditPeople:9 +msgid "Current Watchers" +msgstr "ç¾æœ‰è¦–察員" + #: html/Admin/Groups/Members.html:38 html/User/Groups/Members.html:41 msgid "Current members" msgstr "ç¾æœ‰æˆå“¡" @@ -1670,7 +1694,7 @@ msgstr "ç¾æœ‰æ¬Šé™" msgid "Current search criteria" msgstr "ç¾æœ‰æŸ¥è©¢æ¢ä»¶" -#: html/Admin/Queues/People.html:40 html/Ticket/Elements/EditPeople:44 +#: html/Admin/Queues/People.html:40 html/Ticket/Elements/EditPeople:44 html/Work/Tickets/Elements/EditPeople:32 msgid "Current watchers" msgstr "ç¾æœ‰è¦–察員" @@ -1679,7 +1703,7 @@ msgstr "ç¾æœ‰è¦–察員" msgid "Custom Field #%1" msgstr "è‡ªè¨‚æ¬„ä½ #%1" -#: html/Admin/Elements/QueueTabs:52 html/Admin/Elements/SystemTabs:39 html/Admin/Global/index.html:49 html/Edit/Global/autohandler:7 html/Edit/Queues/autohandler:18 html/Ticket/Elements/ShowSummary:35 +#: html/Admin/Elements/QueueTabs:52 html/Admin/Elements/SystemTabs:39 html/Admin/Global/index.html:49 html/Edit/Global/autohandler:7 html/Edit/Queues/autohandler:22 html/Ticket/Elements/ShowSummary:35 msgid "Custom Fields" msgstr "自訂欄ä½" @@ -1699,31 +1723,31 @@ msgstr "動作å‰åŸ·è¡Œç¨‹å¼" msgid "Custom condition" msgstr "自訂æ¢ä»¶" -#: lib/RT/Tickets_Overlay.pm:1618 +#: lib/RT/Tickets_Overlay.pm:1637 #. ($CF->Name , $args{OPERATOR} , $args{VALUE}) msgid "Custom field %1 %2 %3" msgstr "è‡ªè¨‚æ¬„ä½ %1 %2 %3" -#: lib/RT/Tickets_Overlay.pm:1613 +#: lib/RT/Tickets_Overlay.pm:1632 #. ($CF->Name) msgid "Custom field %1 has a value." msgstr "è‡ªè¨‚æ¬„ä½ %1 已有值" -#: lib/RT/Tickets_Overlay.pm:1610 +#: lib/RT/Tickets_Overlay.pm:1629 #. ($CF->Name) msgid "Custom field %1 has no value." msgstr "è‡ªè¨‚æ¬„ä½ %1 沒有值" -#: lib/RT/Ticket_Overlay.pm:3454 +#: lib/RT/Ticket_Overlay.pm:3510 #. ($args{'Field'}) msgid "Custom field %1 not found" msgstr "找ä¸åˆ°è‡ªè¨‚æ¬„ä½ %1" -#: html/Admin/Elements/EditCustomFields:196 +#: html/Admin/Elements/EditCustomFields:195 msgid "Custom field deleted" msgstr "自訂欄ä½å·²åˆªé™¤" -#: lib/RT/Ticket_Overlay.pm:3604 +#: lib/RT/Ticket_Overlay.pm:3660 msgid "Custom field not found" msgstr "找ä¸åˆ°è‡ªè¨‚欄ä½" @@ -1748,7 +1772,7 @@ msgstr "找ä¸åˆ°è‡ªè¨‚欄ä½å€¼" msgid "Custom field value deleted" msgstr "自訂欄ä½å€¼åˆªé™¤æˆåŠŸ" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:145 html/Edit/Global/Workflow/Owner.html:90 lib/RT/Transaction_Overlay.pm:548 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:145 html/Edit/Global/Workflow/Owner.html:90 lib/RT/Transaction_Overlay.pm:505 lib/RT/Transaction_Vendor.pm:5 msgid "CustomField" msgstr "自訂欄ä½" @@ -1756,11 +1780,19 @@ msgstr "自訂欄ä½" msgid "Data error" msgstr "資料錯誤" +#: html/Edit/Global/Basic/Top:77 +msgid "DatabaseBindRemote" +msgstr "容許外部連線" + +#: html/Edit/Global/Basic/Top:75 +msgid "DatabaseName" +msgstr "MySQL資料庫" + #: NOT FOUND IN SOURCE msgid "Date of Departure" msgstr "出發日期" -#: html/SelfService/Display.html:38 html/Ticket/Create.html:160 html/Ticket/Elements/ShowSummary:54 html/Ticket/Elements/Tabs:92 html/Ticket/ModifyAll.html:43 html/Work/Tickets/Elements/ShowTransaction:14 +#: html/SelfService/Display.html:38 html/Ticket/Create.html:160 html/Ticket/Elements/ShowSummary:54 html/Ticket/Elements/Tabs:92 html/Ticket/ModifyAll.html:43 html/Work/Tickets/Elements/ShowTransaction:17 msgid "Dates" msgstr "日期" @@ -1777,34 +1809,46 @@ msgid "December" msgstr "å二月" #: NOT FOUND IN SOURCE +msgid "Default Approval" +msgstr "é è¨ç°½æ ¸" + +#: NOT FOUND IN SOURCE msgid "Default Autoresponse Template" msgstr "é è¨è‡ªå‹•å›žæ‡‰ç¯„本" -#: etc/initialdata.zh:225 etc/initialdata:207 +#: etc/initialdata:207 msgid "Default Autoresponse template" msgstr "é è¨è‡ªå‹•å›žæ‡‰ç¯„本" -#: etc/initialdata.zh:304 etc/initialdata:281 +#: html/Edit/Global/CustomField/Top:46 +msgid "Default Value" +msgstr "é è¨å€¼" + +#: etc/initialdata:281 msgid "Default admin comment template" msgstr "é è¨ç®¡ç†å“¡è©•è«–範本" -#: etc/initialdata.zh:262 etc/initialdata:260 +#: etc/initialdata:260 msgid "Default admin correspondence template" msgstr "é è¨ç®¡ç†å“¡å›žè¦†ç¯„本" -#: etc/initialdata.zh:283 etc/initialdata:272 +#: etc/initialdata:272 msgid "Default correspondence template" msgstr "é è¨å›žè¦†ç¯„本" -#: etc/initialdata.zh:240 etc/initialdata:238 +#: etc/initialdata:238 msgid "Default transaction template" msgstr "é è¨æ›´å‹•ç¯„本" -#: lib/RT/Transaction_Overlay.pm:643 +#: lib/RT/Transaction_Overlay.pm:491 #. ($type, $self->Field, $self->OldValue, $self->NewValue) msgid "Default: %1/%2 changed from %3 to %4" msgstr "é è¨ï¼š%1/%2 已自 %3 改為 %4" +#: NOT FOUND IN SOURCE +msgid "DefaultApproval" +msgstr "é è¨ç°½æ ¸" + #: html/User/Delegation.html:24 html/User/Delegation.html:27 msgid "Delegate rights" msgstr "代表團權é™" @@ -1833,7 +1877,7 @@ msgstr "代ç†è¡¨å–®ï¼š" msgid "Delegated Type" msgstr "代ç†è¡¨å–®ç¨®é¡ž" -#: html/Edit/Users/index.html:125 html/Work/Delegates/Info:31 html/Work/Delegates/List:8 html/Work/Elements/Tab:41 html/Work/Overview/Info:28 +#: html/Edit/Users/index.html:98 html/Work/Delegates/Info:31 html/Work/Delegates/List:8 html/Work/Elements/Tab:41 html/Work/Overview/Info:28 msgid "Delegates" msgstr "代ç†äºº" @@ -1877,10 +1921,14 @@ msgstr "代ç†äººç¾¤çµ„" msgid "Delegation Rights" msgstr "代ç†äººæ¬Šé™" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:113 html/Edit/Elements/104Buttons:73 html/Work/Search/index.html:48 html/Work/Search/index.html:48 +#: html/Admin/Elements/EditScrips:53 html/Admin/Elements/ModifyTemplateAsWorkflow:113 html/Edit/Elements/104Buttons:84 html/Work/Search/index.html:48 html/Work/Search/index.html:48 msgid "Delete" msgstr "刪除" +#: html/Admin/Elements/EditScrips:52 +msgid "Delete selected scrips" +msgstr "刪除指定的手續" + #: lib/RT/Queue_Overlay.pm:88 msgid "Delete tickets" msgstr "刪除申請單" @@ -1889,7 +1937,7 @@ msgstr "刪除申請單" msgid "DeleteTicket" msgstr "刪除申請單" -#: lib/RT/Transaction_Overlay.pm:187 +#: lib/RT/Transaction_Overlay.pm:136 msgid "Deleting this object could break referential integrity" msgstr "刪除æ¤ç‰©ä»¶å¯èƒ½ç ´å£žåƒè€ƒå®Œæ•´æ€§" @@ -1897,7 +1945,7 @@ msgstr "刪除æ¤ç‰©ä»¶å¯èƒ½ç ´å£žåƒè€ƒå®Œæ•´æ€§" msgid "Deleting this object would break referential integrity" msgstr "刪除æ¤ç‰©ä»¶å¯èƒ½ç ´å£žåƒè€ƒå®Œæ•´æ€§" -#: lib/RT/User_Overlay.pm:499 +#: lib/RT/User_Overlay.pm:504 msgid "Deleting this object would violate referential integrity" msgstr "刪除æ¤ç‰©ä»¶æœƒé•ååƒè€ƒå®Œæ•´æ€§" @@ -1917,11 +1965,11 @@ msgstr "é§å›ž" msgid "Department" msgstr "部門" -#: html/Edit/Global/UserRight/List:12 html/Edit/Global/UserRight/Top:13 html/Edit/Users/List:10 html/Edit/Users/Top:12 +#: html/Edit/Global/UserRight/List:12 html/Edit/Global/UserRight/Top:13 msgid "Department ID" msgstr "部門代碼" -#: html/Edit/Global/UserRight/List:11 html/Edit/Global/UserRight/Top:49 html/Edit/Users/List:9 html/Edit/Users/Top:48 html/Work/Delegates/Info:78 html/Work/Overview/Info:60 +#: html/Edit/Global/UserRight/List:11 html/Edit/Global/UserRight/Top:49 html/Work/Delegates/Info:78 html/Work/Overview/Info:60 msgid "Department Name" msgstr "部門å稱" @@ -1945,7 +1993,7 @@ msgstr "è«‹å‡å–®" msgid "Departure Until" msgstr "差旅截æ¢æ—¥" -#: html/Ticket/Create.html:180 html/Ticket/Elements/BulkLinks:34 html/Ticket/Elements/EditLinks:122 html/Ticket/Elements/EditLinks:46 html/Ticket/Elements/ShowDependencies:31 html/Ticket/Elements/ShowLinks:36 html/Work/Search/BulkLinks:10 +#: html/Ticket/Create.html:181 html/Ticket/Elements/BulkLinks:34 html/Ticket/Elements/EditLinks:105 html/Ticket/Elements/EditLinks:44 html/Ticket/Elements/ShowDependencies:31 html/Ticket/Elements/ShowLinks:36 html/Work/Search/BulkLinks:10 html/Work/Tickets/Elements/EditLinks:109 html/Work/Tickets/Elements/EditLinks:34 html/Work/Tickets/Elements/ShowLinks:21 msgid "Depended on by" msgstr "å¯æŽ¥çºŒè™•ç†çš„申請單" @@ -1953,7 +2001,27 @@ msgstr "å¯æŽ¥çºŒè™•ç†çš„申請單" msgid "Dependencies: \\n" msgstr "附屬性:\\n" -#: html/Elements/SelectLinkType:26 html/Ticket/Create.html:179 html/Ticket/Elements/BulkLinks:30 html/Ticket/Elements/EditLinks:118 html/Ticket/Elements/EditLinks:35 html/Ticket/Elements/ShowDependencies:24 html/Ticket/Elements/ShowLinks:26 html/Work/Search/BulkLinks:6 +#: lib/RT/Transaction_Overlay.pm:585 +#. ($value) +msgid "Dependency by %1 added" +msgstr "å·²åŠ å…¥å¯æŽ¥çºŒè™•ç†çš„申請單 %1" + +#: lib/RT/Transaction_Overlay.pm:622 +#. ($value) +msgid "Dependency by %1 deleted" +msgstr "已移除å¯æŽ¥çºŒè™•ç†çš„申請單 %1" + +#: lib/RT/Transaction_Overlay.pm:582 +#. ($value) +msgid "Dependency on %1 added" +msgstr "å·²åŠ å…¥éœ€å…ˆè™•ç†çš„申請單 %1" + +#: lib/RT/Transaction_Overlay.pm:619 +#. ($value) +msgid "Dependency on %1 deleted" +msgstr "已移除需先處ç†çš„申請單 %1" + +#: html/Elements/SelectLinkType:26 html/Ticket/Create.html:180 html/Ticket/Elements/BulkLinks:30 html/Ticket/Elements/EditLinks:101 html/Ticket/Elements/EditLinks:35 html/Ticket/Elements/ShowDependencies:24 html/Ticket/Elements/ShowLinks:26 html/Work/Search/BulkLinks:6 html/Work/Tickets/Elements/EditLinks:105 html/Work/Tickets/Elements/EditLinks:23 html/Work/Tickets/Elements/ShowLinks:16 msgid "Depends on" msgstr "需先處ç†" @@ -1969,7 +2037,7 @@ msgstr "éžæ¸›" msgid "Describe the issue below" msgstr "在以下欄ä½æ述主題" -#: html/Admin/Elements/AddCustomFieldValue:35 html/Admin/Elements/EditCustomField:38 html/Admin/Elements/EditScrip:33 html/Admin/Elements/ModifyQueue:35 html/Admin/Elements/ModifyTemplate:35 html/Admin/Elements/ModifyTemplateAsWorkflow:192 html/Admin/Groups/Modify.html:48 html/Admin/Queues/Modify.html:47 html/Edit/Global/Workflow/Action:14 html/Elements/SelectGroups:26 html/User/Groups/Modify.html:48 html/Work/Preferences/Info:103 +#: html/Admin/Elements/AddCustomFieldValue:35 html/Admin/Elements/EditCustomField:38 html/Admin/Elements/EditScrip:33 html/Admin/Elements/ModifyQueue:35 html/Admin/Elements/ModifyTemplate:35 html/Admin/Elements/ModifyTemplateAsWorkflow:192 html/Admin/Groups/Modify.html:48 html/Admin/Queues/Modify.html:47 html/Edit/Elements/SelectQueues:4 html/Edit/Global/Workflow/Action:13 html/Elements/SelectGroups:26 html/User/Groups/Modify.html:48 msgid "Description" msgstr "æè¿°" @@ -1981,7 +2049,7 @@ msgstr "經辦æ¥å‹™èªªæ˜Ž" msgid "Description:" msgstr "æ述:" -#: html/Work/Tickets/Create.html:117 html/Work/Tickets/Create.html:85 html/Work/Tickets/Elements/EditCustomFields:13 html/Work/Tickets/Elements/EditCustomFields:47 html/Work/Tickets/Elements/ShowCustomFields:15 html/Work/Tickets/Elements/ShowCustomFields:50 +#: html/Work/Tickets/Create.html:132 html/Work/Tickets/Create.html:84 html/Work/Tickets/Elements/EditCustomFields:13 html/Work/Tickets/Elements/EditCustomFields:61 html/Work/Tickets/Elements/ShowCustomFields:14 html/Work/Tickets/Elements/ShowCustomFields:53 msgid "Details" msgstr "細節" @@ -1989,15 +2057,15 @@ msgstr "細節" msgid "Direct" msgstr "直接" -#: html/Edit/Users/Info:31 +#: NOT FOUND IN SOURCE msgid "Disability" msgstr "殘障身分" -#: html/Edit/Users/Info:29 +#: NOT FOUND IN SOURCE msgid "Disability Type" msgstr "殘障類別" -#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:19 html/Edit/Queues/Basic/Top:70 html/Edit/Queues/List:13 html/Work/Delegates/Info:48 html/Work/Delegates/Info:53 html/Work/Delegates/List:12 html/Work/Overview/Info:42 +#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:19 html/Edit/Queues/Basic/Top:69 html/Edit/Queues/List:15 html/Edit/Queues/List:27 html/Work/Delegates/Info:48 html/Work/Delegates/Info:53 html/Work/Delegates/List:12 html/Work/Overview/Info:42 msgid "Disabled" msgstr "åœç”¨" @@ -2033,7 +2101,7 @@ msgstr "å…許一切æ“作" msgid "Don't refresh this page." msgstr "ä¸æ›´æ–°æ¤é é¢ã€‚" -#: html/Search/Elements/PickRestriction:113 html/Work/Search/PickRestriction:95 +#: html/Search/Elements/PickRestriction:113 html/Work/Search/PickRestriction:101 msgid "Don't show search results" msgstr "ä¸é¡¯ç¤ºæŸ¥è©¢çµæžœ" @@ -2041,7 +2109,7 @@ msgstr "ä¸é¡¯ç¤ºæŸ¥è©¢çµæžœ" msgid "Down" msgstr "下一é " -#: html/Ticket/Elements/ShowTransaction:92 +#: html/Ticket/Elements/ShowTransaction:103 msgid "Download" msgstr "下載" @@ -2049,7 +2117,7 @@ msgstr "下載" msgid "Dr." msgstr "åšå£«" -#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:44 html/Ticket/Elements/ShowDates:42 lib/RT/Ticket_Overlay.pm:1189 +#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:44 html/Ticket/Elements/ShowDates:43 html/Work/Tickets/Elements/EditBasics:54 lib/RT/Ticket_Overlay.pm:1216 msgid "Due" msgstr "到期日" @@ -2066,7 +2134,7 @@ msgstr "無法解讀日期 '%1'" msgid "ERROR: Couldn't load ticket '%1': %2.\\n" msgstr "無法載入申請單 '%1':%2.\\n" -#: html/Work/Tickets/Update.html:46 +#: html/Work/Tickets/Update.html:47 msgid "Edit" msgstr "編輯" @@ -2074,7 +2142,7 @@ msgstr "編輯" msgid "Edit Conditions" msgstr "編輯å‰ç½®æ¢ä»¶" -#: html/Admin/Queues/CustomFields.html:44 +#: html/Admin/Queues/CustomFields.html:45 #. ($Queue->Name) msgid "Edit Custom Fields for %1" msgstr "編輯 %1 的自訂欄ä½" @@ -2168,15 +2236,19 @@ msgstr "最高å¸æ·" msgid "EffectiveId" msgstr "有效編號" -#: lib/RT/Ticket_Overlay.pm:2635 lib/RT/Ticket_Overlay.pm:2703 +#: lib/RT/Ticket_Overlay.pm:2673 lib/RT/Ticket_Overlay.pm:2751 msgid "Either base or target must be specified" msgstr "需è¦æŒ‡å®šèµ·å§‹ç”³è«‹å–®æˆ–目的申請單" -#: html/Admin/Users/Modify.html:52 html/Admin/Users/Prefs.html:45 html/Elements/SelectUsers:26 html/Ticket/Elements/AddWatchers:55 html/User/Prefs.html:41 html/Work/Delegates/Info:96 html/Work/Overview/Info:78 html/Work/Preferences/Info:16 +#: html/Admin/Users/Modify.html:52 html/Admin/Users/Prefs.html:45 html/Edit/Elements/SelectUsers:4 html/Edit/Users/List:7 html/Elements/SelectUsers:26 html/Ticket/Elements/AddWatchers:55 html/User/Prefs.html:43 html/Work/Delegates/Info:96 html/Work/Overview/Info:78 msgid "Email" msgstr "é›»å郵件信箱" -#: lib/RT/User_Overlay.pm:247 +#: html/Work/Preferences/Info:16 +msgid "Email Address" +msgstr "é›»å郵件信箱" + +#: lib/RT/User_Overlay.pm:251 msgid "Email address in use" msgstr "æ¤é›»å郵件信箱已被使用" @@ -2216,11 +2288,11 @@ msgstr "啟用(å–消勾é¸å°‡åœç”¨æ¤ç¾¤çµ„)" msgid "Enabled (Unchecking this box disables this queue)" msgstr "啟用(å–消勾é¸å°‡åœç”¨æ¤è¡¨å–®)" -#: html/Admin/Elements/EditCustomFields:98 +#: html/Admin/Elements/EditCustomFields:97 msgid "Enabled Custom Fields" msgstr "已啟用的自訂欄ä½" -#: html/Edit/Queues/Basic/Top:75 html/Edit/Queues/List:15 +#: html/Edit/Queues/Basic/Top:74 html/Edit/Queues/List:17 html/Edit/Queues/List:29 msgid "Enabled Date" msgstr "啟用日期" @@ -2232,16 +2304,16 @@ msgstr "啟動日期:" msgid "Enabled Queues" msgstr "已啟用的表單" -#: html/Edit/Queues/Basic/Top:66 html/Edit/Queues/List:11 +#: html/Edit/Queues/Basic/Top:65 html/Edit/Queues/List:13 html/Edit/Queues/List:25 msgid "Enabled Status" msgstr "啟用狀態" -#: html/Admin/Elements/EditCustomField:106 html/Admin/Groups/Modify.html:116 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:282 html/User/Groups/Modify.html:116 +#: html/Admin/Elements/EditCustomField:106 html/Admin/Groups/Modify.html:116 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:284 html/User/Groups/Modify.html:116 #. (loc_fuzzy($msg)) msgid "Enabled status %1" msgstr "啟用狀態 %1" -#: html/Edit/Users/Info:34 +#: NOT FOUND IN SOURCE msgid "End of Trial" msgstr "試用期滿日" @@ -2261,7 +2333,7 @@ msgstr "輸入下列單一或複å¼æ¢ä»¶ï¼ŒæŸ¥è©¢ç”¨æˆ¶è³‡æ–™" msgid "Enter one value" msgstr "éµå…¥å–®ä¸€é …ç›®" -#: html/Search/Bulk.html:144 html/Ticket/Elements/EditLinks:111 html/Work/Search/Bulk.html:95 +#: html/Search/Bulk.html:144 html/Ticket/Elements/EditLinks:94 html/Work/Search/Bulk.html:95 html/Work/Tickets/Elements/EditLinks:98 msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces." msgstr "輸入申請單å¯éˆçµåˆ°çš„申請單編號或網å€ã€‚以空白隔開。" @@ -2313,15 +2385,15 @@ msgstr "表單->新增視察員的åƒæ•¸æœ‰èª¤" msgid "Error in parameters to Queue->DelWatcher" msgstr "表單->刪除視察員的åƒæ•¸æœ‰èª¤" -#: lib/RT/Ticket_Overlay.pm:1374 +#: lib/RT/Ticket_Overlay.pm:1401 msgid "Error in parameters to Ticket->AddWatcher" msgstr "申請單->新增視察員的åƒæ•¸æœ‰èª¤" -#: lib/RT/Ticket_Overlay.pm:1531 +#: lib/RT/Ticket_Overlay.pm:1558 msgid "Error in parameters to Ticket->DelWatcher" msgstr "申請單->刪除視察員的åƒæ•¸æœ‰èª¤" -#: etc/initialdata.zh:38 etc/initialdata:20 +#: etc/initialdata:20 msgid "Everyone" msgstr "所有人" @@ -2329,7 +2401,11 @@ msgstr "所有人" msgid "Example:" msgstr "範例:" -#: html/Edit/Elements/104Buttons:77 +#: NOT FOUND IN SOURCE +msgid "Existing user renamed from %1 to %2" +msgstr "ç¾æœ‰ä½¿ç”¨è€… %1 已改å為 %2" + +#: html/Edit/Elements/104Buttons:88 msgid "Export" msgstr "匯出" @@ -2341,31 +2417,31 @@ msgstr "外部èªè‰å¸³è™Ÿ" msgid "ExternalContactInfoId" msgstr "外部è¯çµ¡æ–¹å¼å¸³è™Ÿ" -#: html/Edit/Global/Basic/Top:64 +#: html/Edit/Global/Basic/Top:69 msgid "ExternalDatabaseDSN" msgstr "外部資料庫連çµå—串" -#: html/Edit/Global/Basic/Top:68 +#: html/Edit/Global/Basic/Top:73 msgid "ExternalDatabasePass" msgstr "外部資料庫密碼" -#: html/Edit/Global/Basic/Top:66 +#: html/Edit/Global/Basic/Top:71 msgid "ExternalDatabaseUser" msgstr "外部資料庫用戶" -#: html/Edit/Global/Basic/Top:62 +#: html/Edit/Global/Basic/Top:67 msgid "ExternalURL" msgstr "外部介é¢ç¶²å€" -#: html/Admin/Users/Modify.html:72 +#: html/Admin/Users/Modify.html:72 html/Edit/Users/Info:41 msgid "Extra info" msgstr "備註" -#: lib/RT/User_Overlay.pm:363 +#: lib/RT/User_Overlay.pm:368 msgid "Failed to find 'Privileged' users pseudogroup." msgstr "找ä¸åˆ°ã€Œå…§éƒ¨æˆå“¡ã€è™›æ“¬ç¾¤çµ„的使用者。" -#: lib/RT/User_Overlay.pm:370 +#: lib/RT/User_Overlay.pm:375 msgid "Failed to find 'Unprivileged' users pseudogroup" msgstr "找ä¸åˆ°ã€Œéžå…§éƒ¨æˆå“¡ã€è™›æ“¬ç¾¤çµ„的使用者。" @@ -2390,22 +2466,22 @@ msgstr "二月" msgid "Female" msgstr "女" -#: html/Edit/Global/CustomField/List:5 html/Edit/Global/CustomField/Top:9 -msgid "Field Attribute" -msgstr "欄ä½å±¬æ€§" - #: html/Edit/Global/CustomField/Info:14 msgid "Field Content:" msgstr "欄ä½å…§å®¹ï¼š" -#: html/Edit/Global/CustomField/List:7 html/Edit/Global/CustomField/Top:21 +#: html/Edit/Global/CustomField/List:7 html/Edit/Global/CustomField/Top:20 msgid "Field Description" msgstr "欄ä½æè¿°" -#: html/Edit/Global/CustomField/List:6 html/Edit/Global/CustomField/Top:15 +#: html/Edit/Global/CustomField/List:6 html/Edit/Global/CustomField/Top:14 msgid "Field Name" msgstr "欄ä½å稱" +#: html/Edit/Global/CustomField/List:5 html/Edit/Global/CustomField/Top:9 +msgid "Field Type" +msgstr "欄ä½å±¬æ€§" + #: html/Edit/Elements/PickUsers:52 html/Edit/Users/Add.html:47 msgid "Filter" msgstr "篩é¸" @@ -2422,19 +2498,19 @@ msgstr "篩é¸åˆ—表:" msgid "Fin" msgstr "最終" -#: html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:58 lib/RT/Tickets_Overlay.pm:1091 +#: html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:58 html/Work/Tickets/Elements/EditBasics:52 lib/RT/Tickets_Overlay.pm:1110 msgid "Final Priority" -msgstr "æœ€ä½Žé †ä½" +msgstr "æœ€çµ‚é †ä½" -#: lib/RT/Ticket_Overlay.pm:1180 +#: lib/RT/Ticket_Overlay.pm:1207 msgid "FinalPriority" -msgstr "æœ€ä½Žé †ä½" +msgstr "æœ€çµ‚é †ä½" #: NOT FOUND IN SOURCE msgid "Financial Department:" msgstr "財務部:" -#: html/Admin/Queues/People.html:60 html/Ticket/Elements/EditPeople:33 +#: html/Admin/Queues/People.html:60 html/Ticket/Elements/EditPeople:33 html/Work/Tickets/Elements/EditPeople:18 msgid "Find group whose" msgstr "尋找群組的" @@ -2442,10 +2518,14 @@ msgstr "尋找群組的" msgid "Find new/open tickets" msgstr "尋找/開啟申請單" -#: html/Admin/Queues/People.html:56 html/Admin/Users/index.html:45 html/Ticket/Elements/EditPeople:29 +#: html/Admin/Queues/People.html:56 html/Admin/Users/index.html:45 html/Edit/Users/Top:6 html/Ticket/Elements/EditPeople:29 html/Work/Tickets/Elements/EditPeople:14 msgid "Find people whose" msgstr "尋找人員的" +#: html/Edit/Queues/Top:6 +msgid "Find queues whose" +msgstr "尋找表單的" + #: html/Search/Listing.html:107 html/Work/Search/index.html:88 msgid "Find tickets" msgstr "尋找申請單" @@ -2470,7 +2550,7 @@ msgstr "一" msgid "First-level Admins" msgstr "一階主管" -#: html/Edit/Users/Info:39 +#: NOT FOUND IN SOURCE msgid "First-level Users" msgstr "一階主管員工" @@ -2478,17 +2558,17 @@ msgstr "一階主管員工" msgid "Fixed shift" msgstr "固定ç" -#: docs/design_docs/string-extraction-guide.txt:33 +#: docs/design_docs/string-extraction-guide.txt:33 lib/RT/StyleGuide.pod:746 msgid "Foo Bar Baz" msgstr "甲 ä¹™ 丙" -#: docs/design_docs/string-extraction-guide.txt:24 +#: docs/design_docs/string-extraction-guide.txt:24 lib/RT/StyleGuide.pod:737 msgid "Foo!" msgstr "甲ï¼" #: html/Search/Bulk.html:86 html/Work/Search/Bulk.html:55 msgid "Force change" -msgstr "強制更新" +msgstr "強制更æ›" #: html/Work/Elements/104Header:89 msgid "Form Processing" @@ -2499,7 +2579,7 @@ msgstr "é›»å表單作æ¥å€" msgid "Found %quant(%1,ticket)" msgstr "找到 %1 張申請單" -#: lib/RT/Interface/Web.pm:904 x:907 +#: lib/RT/Interface/Web.pm:964 msgid "Found Object" msgstr "已找到物件" @@ -2555,7 +2635,7 @@ msgstr "完整標é 檔" msgid "Gecos" msgstr "登入帳號" -#: html/Edit/Users/Info:26 +#: NOT FOUND IN SOURCE msgid "Gender" msgstr "性別" @@ -2563,7 +2643,7 @@ msgstr "性別" msgid "Getting the current user from a pgp sig\\n" msgstr "å–å¾—ç›®å‰ä½¿ç”¨è€…çš„ pgp ç°½ç« \\n" -#: lib/RT/Transaction_Overlay.pm:593 +#: lib/RT/Transaction_Overlay.pm:551 #. ($New->Name) msgid "Given to %1" msgstr "交予 %1" @@ -2573,6 +2653,10 @@ msgid "Global" msgstr "全域è¨å®š" #: NOT FOUND IN SOURCE +msgid "Global Approval" +msgstr "å…¨åŸŸç°½æ ¸" + +#: NOT FOUND IN SOURCE msgid "Global Keyword Selections" msgstr "全域關éµå—é¸å–" @@ -2593,7 +2677,11 @@ msgstr "全域è¨å®š" msgid "Global template: %1" msgstr "全域範本:%1" -#: html/Admin/Elements/EditCustomFields:74 html/Admin/Queues/People.html:58 html/Admin/Queues/People.html:62 html/Admin/Queues/index.html:43 html/Admin/Users/index.html:48 html/Ticket/Elements/EditPeople:31 html/Ticket/Elements/EditPeople:35 html/index.html:40 +#: NOT FOUND IN SOURCE +msgid "GlobalApproval" +msgstr "å…¨åŸŸç°½æ ¸" + +#: html/Admin/Elements/EditCustomFields:73 html/Admin/Queues/People.html:58 html/Admin/Queues/People.html:62 html/Admin/Queues/index.html:43 html/Admin/Users/index.html:48 html/Ticket/Elements/EditPeople:31 html/Ticket/Elements/EditPeople:35 html/Work/Tickets/Elements/EditPeople:16 html/Work/Tickets/Elements/EditPeople:20 html/index.html:40 msgid "Go!" msgstr "執行" @@ -2621,6 +2709,10 @@ msgstr "群組" msgid "Group %1 %2: %3" msgstr "群組 %1 %2:%3" +#: NOT FOUND IN SOURCE +msgid "Group Admin" +msgstr "群組管ç†å“¡" + #: html/Edit/Global/GroupRight/List:5 html/Edit/Global/GroupRight/Top:20 html/Edit/Groups/List:7 msgid "Group Description" msgstr "群組æè¿°" @@ -2633,7 +2725,7 @@ msgstr "群組管ç†" msgid "Group Members" msgstr "群組æˆå“¡" -#: html/Edit/Elements/PickUsers:28 html/Edit/Global/GroupRight/List:4 html/Edit/Global/GroupRight/Top:10 html/Edit/Groups/List:6 html/Edit/Groups/Top:7 html/Edit/Users/Add.html:29 html/Edit/Users/Group:10 html/Edit/Users/Search.html:43 html/Work/Delegates/Add.html:15 html/Work/Tickets/Cc:24 +#: html/Edit/Elements/PickUsers:28 html/Edit/Global/GroupRight/List:4 html/Edit/Global/GroupRight/Top:10 html/Edit/Groups/List:6 html/Edit/Groups/Top:7 html/Edit/Queues/Basic/Add.html:15 html/Edit/Users/Add.html:29 html/Edit/Users/Group:10 html/Edit/Users/Search.html:43 html/Work/Delegates/Add.html:15 html/Work/Tickets/Cc:24 msgid "Group Name" msgstr "群組å稱" @@ -2641,7 +2733,7 @@ msgstr "群組å稱" msgid "Group Name:" msgstr "群組å稱:" -#: html/Admin/Elements/GroupTabs:44 html/Admin/Elements/QueueTabs:56 html/Admin/Elements/SystemTabs:43 html/Admin/Global/index.html:54 html/Edit/Global/autohandler:12 html/Edit/Queues/autohandler:23 html/Edit/Users/Group:11 html/Edit/Users/index.html:123 +#: html/Admin/Elements/GroupTabs:44 html/Admin/Elements/QueueTabs:56 html/Admin/Elements/SystemTabs:43 html/Admin/Global/index.html:54 html/Edit/Global/autohandler:12 html/Edit/Queues/autohandler:27 html/Edit/Users/Group:11 html/Edit/Users/index.html:96 msgid "Group Rights" msgstr "群組權é™" @@ -2657,7 +2749,7 @@ msgstr "群組è¨å®š" msgid "Group Status" msgstr "群組狀態" -#: lib/RT/Group_Overlay.pm:964 +#: lib/RT/Group_Overlay.pm:962 msgid "Group already has member" msgstr "群組內已有æ¤æˆå“¡" @@ -2670,15 +2762,19 @@ msgstr "無法新增群組" msgid "Group could not be created: %1" msgstr "無法新增群組:%1" -#: lib/RT/Group_Overlay.pm:496 +#: lib/RT/Group_Overlay.pm:494 msgid "Group created" msgstr "群組新增完畢" -#: lib/RT/Group_Overlay.pm:1132 +#: NOT FOUND IN SOURCE +msgid "Group created: %1" +msgstr "群組 %1 新增完畢" + +#: lib/RT/Group_Overlay.pm:1134 msgid "Group has no such member" msgstr "群組沒有這個æˆå“¡" -#: lib/RT/Group_Overlay.pm:944 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1428 lib/RT/Ticket_Overlay.pm:1506 +#: lib/RT/Group_Overlay.pm:942 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1455 lib/RT/Ticket_Overlay.pm:1533 msgid "Group not found" msgstr "找ä¸åˆ°ç¾¤çµ„" @@ -2691,6 +2787,14 @@ msgid "Group not specified.\\n" msgstr "未指定群組。\\n" #: NOT FOUND IN SOURCE +msgid "Group redescribed from %1 to %2" +msgstr "群組æè¿° %1 已改為 %2" + +#: NOT FOUND IN SOURCE +msgid "Group renamed from %1 to %2" +msgstr "群組 %1 已改å為 %2" + +#: NOT FOUND IN SOURCE msgid "Group with Queue Rights" msgstr "æ“有表單權é™ç¾¤çµ„" @@ -2702,11 +2806,11 @@ msgstr "群組之" msgid "Group:" msgstr "群組:" -#: html/Admin/Elements/SelectNewGroupMembers:34 html/Admin/Elements/Tabs:34 html/Admin/Groups/Members.html:63 html/Admin/Queues/People.html:82 html/Admin/index.html:31 html/Edit/Global/GroupRight/Add.html:15 html/User/Groups/Members.html:66 +#: html/Admin/Elements/SelectNewGroupMembers:34 html/Admin/Elements/Tabs:34 html/Admin/Groups/Members.html:63 html/Admin/Queues/People.html:82 html/Admin/index.html:31 html/Edit/Global/GroupRight/Add.html:16 html/Edit/Groups/Admin:12 html/User/Groups/Members.html:66 msgid "Groups" msgstr "群組" -#: lib/RT/Group_Overlay.pm:970 +#: lib/RT/Group_Overlay.pm:968 msgid "Groups can't be members of their members" msgstr "ä¸èƒ½å°‡ç¾¤çµ„è¨ç‚ºç¾¤çµ„å…§æˆå“¡" @@ -2726,19 +2830,23 @@ msgstr "å¥ä¿è£œåŠ©èº«ä»½" msgid "Hello!" msgstr "å—¨ï¼" -#: docs/design_docs/string-extraction-guide.txt:40 +#: docs/design_docs/string-extraction-guide.txt:40 lib/RT/StyleGuide.pod:753 #. ($name) msgid "Hello, %1" msgstr "嗨,%1" #: html/Edit/Elements/104Top:28 msgid "Help" -msgstr "輔助說明" +msgstr "說明" #: NOT FOUND IN SOURCE msgid "Help Desks" msgstr "å„é …æ¥å‹™çª—å£" +#: html/Edit/Global/CustomField/SelectWritable:9 html/Edit/Queues/Basic/Top:80 +msgid "Hidden" +msgstr "éš±è—" + #: html/Ticket/Elements/ShowHistory:29 html/Ticket/Elements/Tabs:87 html/Work/Tickets/Elements/ShowHistory:8 msgid "History" msgstr "紀錄" @@ -2755,7 +2863,7 @@ msgstr "主é " msgid "Hotel Expense" msgstr "ä½å®¿è²»" -#: lib/RT/Base.pm:73 +#: lib/RT/Base.pm:75 #. (6) msgid "I have %quant(%1,concrete mixer)." msgstr "我有 %quant(%1,份固體攪拌器)。" @@ -2768,7 +2876,7 @@ msgstr "身分è‰è™Ÿ" msgid "ID Type" msgstr "身分類別" -#: html/Ticket/Elements/ShowBasics:26 lib/RT/Tickets_Overlay.pm:1018 +#: html/Ticket/Elements/ShowBasics:26 lib/RT/Tickets_Overlay.pm:1037 msgid "Id" msgstr "編號" @@ -2776,7 +2884,7 @@ msgstr "編號" msgid "Identity" msgstr "身份" -#: etc/initialdata.zh:439 etc/initialdata:411 etc/upgrade/2.1.71:86 html/Edit/Elements/CreateApprovalsQueue:58 +#: etc/initialdata:411 etc/upgrade/2.1.71:86 html/Edit/Elements/CreateApprovalsQueue:58 msgid "If an approval is rejected, reject the original and delete pending approvals" msgstr "è‹¥ç°½æ ¸å–®é到é§å›žï¼Œå‰‡é€£å¸¶é§å›žåŽŸç”³è«‹å–®ï¼Œä¸¦åˆªé™¤å…¶ä»–ç›¸é—œçš„å¾…ç°½æ ¸äº‹é …" @@ -2788,43 +2896,43 @@ msgstr "如果æ¤å·¥å…·ç¨‹å¼ç‚º setgid,惡æ„的本地端用戶å³èƒ½ç”±æ¤å msgid "If you've updated anything above, be sure to" msgstr "若您已更新以上資料,請記得按一下" -#: lib/RT/Interface/Web.pm:896 x:899 +#: lib/RT/Interface/Web.pm:956 msgid "Illegal value for %1" msgstr "%1 的值錯誤" -#: lib/RT/Interface/Web.pm:899 x:902 +#: lib/RT/Interface/Web.pm:959 msgid "Immutable field" msgstr "æ¤æ¬„ä½å€¼ä¸å¯æ›´å‹•" -#: html/Edit/Elements/104Buttons:76 html/Edit/Global/Workflow/Import.html:2 +#: html/Edit/Elements/104Buttons:87 html/Edit/Global/Workflow/Import.html:2 msgid "Import" msgstr "匯入" -#: html/Admin/Elements/EditCustomFields:73 +#: html/Admin/Elements/EditCustomFields:72 msgid "Include disabled custom fields in listing." msgstr "列出åœç”¨çš„自訂欄ä½" -#: html/Admin/Queues/index.html:42 html/Edit/Queues/index.html:38 +#: html/Admin/Queues/index.html:42 html/Edit/Queues/Top:9 msgid "Include disabled queues in listing." msgstr "列出åœç”¨çš„表單" -#: html/Admin/Users/index.html:46 html/Edit/Users/Search.html:62 +#: html/Admin/Users/index.html:46 html/Edit/Users/Search.html:62 html/Edit/Users/Top:9 msgid "Include disabled users in search." msgstr "列出åœç”¨çš„使用者" -#: html/Edit/Users/Info:36 +#: NOT FOUND IN SOURCE msgid "Indirect Employee" msgstr "直接/間接員工" -#: lib/RT/Tickets_Overlay.pm:1067 +#: lib/RT/Tickets_Overlay.pm:1086 msgid "Initial Priority" -msgstr "åˆå§‹å„ªå…ˆæ¬Š" +msgstr "åˆå§‹å„ªå…ˆé †ä½" -#: lib/RT/Ticket_Overlay.pm:1179 lib/RT/Ticket_Overlay.pm:1181 +#: lib/RT/Ticket_Overlay.pm:1206 lib/RT/Ticket_Overlay.pm:1208 msgid "InitialPriority" -msgstr "åˆå§‹å„ªå…ˆæ¬Š" +msgstr "åˆå§‹å„ªå…ˆé †ä½" -#: lib/RT/ScripAction_Overlay.pm:104 +#: lib/RT/ScripAction_Overlay.pm:105 msgid "Input error" msgstr "輸入錯誤" @@ -2832,7 +2940,7 @@ msgstr "輸入錯誤" msgid "Interest noted" msgstr "登記æˆåŠŸ" -#: lib/RT/Ticket_Overlay.pm:3829 +#: lib/RT/Ticket_Overlay.pm:3913 msgid "Internal Error" msgstr "內部錯誤" @@ -2841,7 +2949,7 @@ msgstr "內部錯誤" msgid "Internal Error: %1" msgstr "內部錯誤:%1" -#: lib/RT/Group_Overlay.pm:643 +#: lib/RT/Group_Overlay.pm:641 msgid "Invalid Group Type" msgstr "錯誤的群組類別" @@ -2853,15 +2961,15 @@ msgstr "錯誤的權é™" msgid "Invalid Type" msgstr "錯誤的類型" -#: lib/RT/Interface/Web.pm:901 x:904 +#: lib/RT/Interface/Web.pm:961 msgid "Invalid data" msgstr "錯誤的資料" -#: lib/RT/Ticket_Overlay.pm:439 +#: lib/RT/Ticket_Overlay.pm:463 msgid "Invalid owner. Defaulting to 'nobody'." msgstr "錯誤的承辦人。改為é è¨æ‰¿è¾¦äººã€Œnobodyã€ã€‚" -#: lib/RT/Scrip_Overlay.pm:133 lib/RT/Template_Overlay.pm:250 +#: lib/RT/Scrip_Overlay.pm:133 lib/RT/Template_Overlay.pm:251 msgid "Invalid queue" msgstr "錯誤的表單" @@ -2874,11 +2982,11 @@ msgstr "錯誤的權é™" msgid "Invalid value for %1" msgstr "%1 的值錯誤" -#: lib/RT/Ticket_Overlay.pm:3461 +#: lib/RT/Ticket_Overlay.pm:3517 msgid "Invalid value for custom field" msgstr "錯誤的自訂欄ä½å€¼" -#: lib/RT/Ticket_Overlay.pm:346 +#: lib/RT/Ticket_Overlay.pm:365 msgid "Invalid value for status" msgstr "錯誤的狀態值" @@ -2936,7 +3044,7 @@ msgstr "七月" #: lib/RT/Date.pm:417 msgid "Jul." -msgstr "01" +msgstr "07" #: NOT FOUND IN SOURCE msgid "July" @@ -2952,7 +3060,7 @@ msgstr "å…月" #: lib/RT/Date.pm:416 msgid "Jun." -msgstr "06." +msgstr "06" #: NOT FOUND IN SOURCE msgid "June" @@ -2982,11 +3090,15 @@ msgstr "éˆçµæ¨™ç±¤" msgid "Lang" msgstr "使用語言" +#: html/User/Prefs.html:54 html/Work/Preferences/Info:29 +msgid "Language" +msgstr "語言" + #: html/Ticket/Elements/Tabs:72 msgid "Last" msgstr "上次更新" -#: html/Ticket/Elements/EditDates:37 html/Ticket/Elements/ShowDates:38 +#: html/Ticket/Elements/EditDates:37 html/Ticket/Elements/ShowDates:39 html/Work/Tickets/Elements/EditBasics:44 msgid "Last Contact" msgstr "上次è¯çµ¡" @@ -3010,11 +3122,11 @@ msgstr "上次更新" msgid "Left" msgstr "剩餘時間" -#: html/Admin/Users/Modify.html:82 +#: html/Admin/Users/Modify.html:82 html/Edit/Users/Info:62 msgid "Let this user access RT" msgstr "å…許這å使用者登入" -#: html/Admin/Users/Modify.html:86 +#: html/Admin/Users/Modify.html:86 html/Edit/Users/Info:68 msgid "Let this user be granted rights" msgstr "內部æˆå“¡ï¼ˆå…·æœ‰å€‹äººæ¬Šé™ï¼‰" @@ -3030,25 +3142,25 @@ msgstr "é™åˆ¶è¡¨å–®ç‚º %1 到 %2" msgid "Link a Queue" msgstr "申請表單連çµ" -#: lib/RT/Ticket_Overlay.pm:2717 +#: lib/RT/Ticket_Overlay.pm:2765 msgid "Link already exists" msgstr "æ¤éˆçµå·²å˜åœ¨" -#: lib/RT/Ticket_Overlay.pm:2729 +#: lib/RT/Ticket_Overlay.pm:2777 msgid "Link could not be created" msgstr "無法新增éˆçµ" -#: lib/RT/Ticket_Overlay.pm:2737 lib/RT/Ticket_Overlay.pm:2747 +#: lib/RT/Ticket_Overlay.pm:2785 lib/RT/Ticket_Overlay.pm:2797 #. ($TransString) msgid "Link created (%1)" msgstr "éˆçµ(%1)新增完畢" -#: lib/RT/Ticket_Overlay.pm:2658 +#: lib/RT/Ticket_Overlay.pm:2698 #. ($TransString) msgid "Link deleted (%1)" msgstr "éˆçµ(%1)刪除完畢" -#: lib/RT/Ticket_Overlay.pm:2664 +#: lib/RT/Ticket_Overlay.pm:2704 msgid "Link not found" msgstr "找ä¸åˆ°éˆçµ" @@ -3069,20 +3181,20 @@ msgstr "éˆçµ" msgid "List All Users" msgstr "列出所有用戶資料" -#: html/Admin/Users/Modify.html:113 html/User/Prefs.html:84 html/Work/Preferences/Info:73 +#: html/Admin/Users/Modify.html:113 html/User/Prefs.html:107 html/Work/Preferences/Info:75 msgid "Location" msgstr "ä½ç½®" -#: lib/RT.pm:162 +#: lib/RT.pm:174 #. ($RT::LogDir) msgid "Log directory %1 not found or couldn't be written.\\n RT can't run." msgstr "登入目錄 %1 找ä¸åˆ°æˆ–無法寫入\\n。無法執行 RT。" -#: html/Edit/Global/Basic/Top:52 +#: html/Edit/Global/Basic/Top:57 msgid "LogToFile" msgstr "紀錄ç‰ç´š" -#: html/Edit/Global/Basic/Top:54 +#: html/Edit/Global/Basic/Top:59 msgid "LogToFileNamed" msgstr "紀錄檔å" @@ -3091,7 +3203,7 @@ msgstr "紀錄檔å" msgid "Logged in as %1" msgstr "使用者:%1" -#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54 +#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54 lib/RT/StyleGuide.pod:777 msgid "Login" msgstr "登入" @@ -3183,6 +3295,10 @@ msgstr "三月" msgid "Marketing Department" msgstr "行銷部" +#: html/Edit/Global/CustomField/Top:63 +msgid "Match Pattern" +msgstr "符åˆæ¨£å¼" + #: NOT FOUND IN SOURCE msgid "May" msgstr "五月" @@ -3191,23 +3307,33 @@ msgstr "五月" msgid "May." msgstr "05" -#: lib/RT/Group_Overlay.pm:981 +#: lib/RT/Transaction_Overlay.pm:598 +#. ($value) +msgid "Member %1 added" +msgstr "æˆå“¡ %1 新增完畢" + +#: lib/RT/Transaction_Overlay.pm:635 +#. ($value) +msgid "Member %1 deleted" +msgstr "æˆå“¡ %1 刪除完畢" + +#: lib/RT/Group_Overlay.pm:979 msgid "Member added" msgstr "新增æˆå“¡å®Œç•¢" -#: lib/RT/Group_Overlay.pm:1139 +#: lib/RT/Group_Overlay.pm:1141 msgid "Member deleted" msgstr "æˆå“¡å·²åˆªé™¤" -#: lib/RT/Group_Overlay.pm:1143 +#: lib/RT/Group_Overlay.pm:1145 msgid "Member not deleted" -msgstr "æˆå“¡æœªè¢«åˆªé™¤" +msgstr "æˆå“¡æœªåˆªé™¤" #: html/Elements/SelectLinkType:25 msgid "Member of" msgstr "隸屬於" -#: html/Work/Preferences/index.html:20 +#: html/Work/Preferences/index.html:19 msgid "Member since" msgstr "註冊日期" @@ -3219,15 +3345,25 @@ msgstr "隸屬於" msgid "Members" msgstr "æˆå“¡" -#: lib/RT/Ticket_Overlay.pm:2904 +#: lib/RT/Transaction_Overlay.pm:595 +#. ($value) +msgid "Membership in %1 added" +msgstr "所屬群組 %1 åŠ å…¥å®Œç•¢" + +#: lib/RT/Transaction_Overlay.pm:632 +#. ($value) +msgid "Membership in %1 deleted" +msgstr "所屬群組 %1 移除完畢" + +#: lib/RT/Ticket_Overlay.pm:2954 msgid "Merge Successful" msgstr "æ•´åˆå®Œç•¢" -#: lib/RT/Ticket_Overlay.pm:2824 +#: lib/RT/Ticket_Overlay.pm:2874 msgid "Merge failed. Couldn't set EffectiveId" msgstr "æ•´åˆå¤±æ•—。無法è¨å®š EffectiveId" -#: html/Ticket/Elements/BulkLinks:26 html/Ticket/Elements/EditLinks:114 html/Work/Search/BulkLinks:2 +#: html/Ticket/Elements/BulkLinks:26 html/Ticket/Elements/EditLinks:97 html/Work/Search/BulkLinks:2 html/Work/Tickets/Elements/EditLinks:101 msgid "Merge into" msgstr "æ•´åˆé€²" @@ -3235,15 +3371,19 @@ msgstr "æ•´åˆé€²" msgid "Message" msgstr "訊æ¯" +#: html/Ticket/Elements/ShowTransaction:80 +msgid "Message body not shown because it is too large or is not plain text." +msgstr "信件內文ä¸æ˜¯ç´”æ–‡å—ï¼Œå› æ¤ç„¡æ³•é¡¯ç¤ºã€‚" + #: NOT FOUND IN SOURCE msgid "Misc. Expense" msgstr "雜費" -#: lib/RT/Interface/Web.pm:903 x:906 +#: lib/RT/Interface/Web.pm:963 msgid "Missing a primary key?: %1" msgstr "缺少主éµå€¼ï¼Ÿ(%1)" -#: html/Admin/Users/Modify.html:168 html/User/Prefs.html:53 html/Work/Preferences/Info:36 +#: html/Admin/Users/Modify.html:168 html/User/Prefs.html:71 html/Work/Preferences/Info:38 msgid "Mobile" msgstr "行動電話" @@ -3400,7 +3540,7 @@ msgstr "更改群組 %1" msgid "Modify the queue watchers" msgstr "更改表單視察員" -#: html/Admin/Users/Modify.html:235 +#: html/Admin/Users/Modify.html:237 #. ($UserObj->Name) msgid "Modify the user %1" msgstr "更改使用者 %1" @@ -3508,7 +3648,7 @@ msgstr "上移" msgid "Multiple" msgstr "多é‡" -#: lib/RT/User_Overlay.pm:238 +#: lib/RT/User_Overlay.pm:242 msgid "Must specify 'Name' attribute" msgstr "å¿…é ˆæŒ‡å®š 'Name' 的屬性" @@ -3533,15 +3673,15 @@ msgstr "表單處ç†" msgid "My approvals" msgstr "è¡¨å–®ç°½æ ¸" -#: html/Admin/Elements/AddCustomFieldValue:31 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/ModifyTemplate:27 html/Admin/Elements/ModifyTemplateAsWorkflow:185 html/Admin/Elements/ModifyUser:29 html/Admin/Groups/Modify.html:43 html/Edit/Users/Add.html:22 html/Edit/Users/Search.html:31 html/Elements/SelectGroups:25 html/Elements/SelectUsers:27 html/User/Groups/Modify.html:43 html/Work/Tickets/Cc:18 +#: html/Admin/Elements/AddCustomFieldValue:31 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/ModifyTemplate:27 html/Admin/Elements/ModifyTemplateAsWorkflow:185 html/Admin/Elements/ModifyUser:29 html/Admin/Groups/Modify.html:43 html/Edit/Elements/SelectQueues:3 html/Edit/Queues/List:8 html/Edit/Users/Add.html:22 html/Edit/Users/List:5 html/Edit/Users/Search.html:31 html/Elements/SelectGroups:25 html/Elements/SelectUsers:27 html/User/Groups/Modify.html:43 html/Work/Tickets/Cc:18 msgid "Name" msgstr "å稱" -#: lib/RT/User_Overlay.pm:245 +#: lib/RT/User_Overlay.pm:249 msgid "Name in use" msgstr "帳號已有人使用" -#: html/Edit/Users/Info:27 +#: NOT FOUND IN SOURCE msgid "Nationality" msgstr "國ç±" @@ -3549,23 +3689,23 @@ msgstr "國ç±" msgid "Need approval from system administrator" msgstr "需先由系統管ç†å“¡é€²è¡Œæ‰¹å‡†" -#: html/Ticket/Elements/ShowDates:51 +#: html/Ticket/Elements/ShowDates:52 msgid "Never" msgstr "從未更動" -#: html/Elements/Quicksearch:29 html/Work/Elements/Quicksearch:15 html/Work/Tickets/Create.html:54 +#: html/Elements/Quicksearch:29 html/Work/Elements/Quicksearch:15 html/Work/Tickets/Create.html:53 msgid "New" msgstr "新建立" -#: html/Admin/Elements/ModifyUser:31 html/Admin/Users/Modify.html:92 html/User/Prefs.html:64 html/Work/Preferences/Info:47 +#: html/Admin/Elements/ModifyUser:31 html/Admin/Users/Modify.html:92 html/Edit/Users/Info:33 html/User/Prefs.html:87 html/Work/Preferences/Info:49 msgid "New Password" msgstr "新的密碼" -#: etc/initialdata.zh:341 etc/initialdata:317 etc/upgrade/2.1.71:16 html/Edit/Elements/CreateApprovalsQueue:21 +#: etc/initialdata:317 etc/upgrade/2.1.71:16 html/Edit/Elements/CreateApprovalsQueue:21 msgid "New Pending Approval" msgstr "æ–°çš„å¾…ç°½æ ¸äº‹é …" -#: html/Ticket/Elements/EditLinks:110 +#: html/Ticket/Elements/EditLinks:93 html/Work/Tickets/Elements/EditLinks:12 msgid "New Relationships" msgstr "新增關係" @@ -3577,7 +3717,11 @@ msgstr "表單申請" msgid "New Search" msgstr "新增查詢" -#: html/Admin/Global/CustomField.html:40 html/Admin/Global/CustomFields.html:38 html/Admin/Queues/CustomField.html:51 html/Admin/Queues/CustomFields.html:39 +#: html/Work/Tickets/Elements/EditPeople:7 +msgid "New Watchers" +msgstr "新增視察員" + +#: html/Admin/Global/CustomField.html:40 html/Admin/Global/CustomFields.html:38 html/Admin/Queues/CustomField.html:51 html/Admin/Queues/CustomFields.html:40 msgid "New custom field" msgstr "新增自訂欄ä½" @@ -3589,7 +3733,7 @@ msgstr "新增群組" msgid "New password" msgstr "新的密碼" -#: lib/RT/User_Overlay.pm:764 +#: lib/RT/User_Overlay.pm:769 msgid "New password notification sent" msgstr "é€å‡ºæ–°å¯†ç¢¼é€šçŸ¥" @@ -3621,7 +3765,7 @@ msgstr "新增範本" msgid "New ticket" msgstr "æ出申請單" -#: lib/RT/Ticket_Overlay.pm:2791 +#: lib/RT/Ticket_Overlay.pm:2841 msgid "New ticket doesn't exist" msgstr "沒有新申請單" @@ -3657,7 +3801,7 @@ msgstr "下一é " msgid "NickName" msgstr "暱稱" -#: html/Admin/Users/Modify.html:62 html/User/Prefs.html:45 html/Work/Preferences/Info:26 +#: html/Admin/Users/Modify.html:62 html/User/Prefs.html:50 html/Work/Preferences/Info:26 msgid "Nickname" msgstr "暱稱" @@ -3665,11 +3809,11 @@ msgstr "暱稱" msgid "Night Shift" msgstr "å°å¤œç" -#: html/Edit/Global/Basic/Top:27 +#: html/Edit/Global/Basic/Top:27 html/Edit/Queues/Basic/Top:83 msgid "No" msgstr "å¦" -#: html/Admin/Elements/EditCustomField:89 html/Admin/Elements/EditCustomFields:104 +#: html/Admin/Elements/EditCustomField:89 html/Admin/Elements/EditCustomFields:103 msgid "No CustomField" msgstr "無自訂欄ä½" @@ -3705,7 +3849,7 @@ msgstr "沒有æµç¨‹" msgid "No action" msgstr "æš«ä¸è™•ç†" -#: lib/RT/Interface/Web.pm:898 x:901 +#: lib/RT/Interface/Web.pm:958 msgid "No column specified" msgstr "未指定欄ä½" @@ -3717,7 +3861,7 @@ msgstr "找ä¸åˆ°å‘½ä»¤" msgid "No comment entered about this user" msgstr "沒有å°é€™å使用者的評論" -#: lib/RT/Ticket_Overlay.pm:2202 lib/RT/Ticket_Overlay.pm:2270 +#: lib/RT/Ticket_Overlay.pm:2229 lib/RT/Ticket_Overlay.pm:2299 msgid "No correspondence attached" msgstr "沒有附上申請單回覆" @@ -3726,11 +3870,11 @@ msgstr "沒有附上申請單回覆" msgid "No description for %1" msgstr "æ²’æœ‰å° %1 çš„æè¿°" -#: lib/RT/Users_Overlay.pm:150 +#: lib/RT/Users_Overlay.pm:149 msgid "No group specified" msgstr "未指定群組" -#: lib/RT/User_Overlay.pm:982 +#: lib/RT/User_Overlay.pm:987 msgid "No password set" msgstr "沒有è¨å®šå¯†ç¢¼" @@ -3738,24 +3882,24 @@ msgstr "沒有è¨å®šå¯†ç¢¼" msgid "No permission to create queues" msgstr "沒有新增表單的權é™" -#: lib/RT/Ticket_Overlay.pm:342 +#: lib/RT/Ticket_Overlay.pm:361 #. ($QueueObj->Name) msgid "No permission to create tickets in the queue '%1'" msgstr "沒有在表單 '%1' 新增申請單的權é™" -#: lib/RT/User_Overlay.pm:211 +#: lib/RT/User_Overlay.pm:208 msgid "No permission to create users" msgstr "沒有新增使用者的權é™" -#: html/SelfService/Display.html:117 +#: html/SelfService/Display.html:123 msgid "No permission to display that ticket" msgstr "沒有顯示該申請單的權é™" -#: html/SelfService/Update.html:51 +#: html/SelfService/Update.html:68 msgid "No permission to view update ticket" msgstr "沒有檢視申請單更新的權é™" -#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1487 +#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1514 msgid "No principal specified" msgstr "未指定單ä½" @@ -3771,7 +3915,7 @@ msgstr "%1 內未指定å”定" msgid "No queues matching search criteria found." msgstr "找ä¸åˆ°ç¬¦åˆæŸ¥è©¢æ¢ä»¶çš„表單。" -#: html/Admin/Elements/SelectRights:80 +#: html/Admin/Elements/SelectRights:81 msgid "No rights found" msgstr "找ä¸åˆ°æ¬Šé™" @@ -3787,7 +3931,7 @@ msgstr "沒有è¦é€²è¡Œçš„查詢" msgid "No ticket id specified" msgstr "未指定申請單編號" -#: lib/RT/Transaction_Overlay.pm:478 lib/RT/Transaction_Overlay.pm:516 +#: lib/RT/Transaction_Overlay.pm:427 lib/RT/Transaction_Overlay.pm:465 msgid "No transaction type specified" msgstr "æœªæŒ‡å®šæ›´å‹•å ±å‘Šé¡žåˆ¥" @@ -3803,7 +3947,7 @@ msgstr "找ä¸åˆ°ç¬¦åˆæŸ¥è©¢æ¢ä»¶çš„使用者。" msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n" msgstr "找ä¸åˆ°åˆæ ¼çš„ RT 使用者。RT cvs 處ç†å™¨å·²åœç”¨ã€‚è«‹å‘ RT 管ç†è€…è©¢å•ã€‚\\n" -#: lib/RT/Interface/Web.pm:895 x:898 +#: lib/RT/Interface/Web.pm:955 msgid "No value sent to _Set!\\n" msgstr "_Set 沒有收到任何值!\\n" @@ -3811,7 +3955,7 @@ msgstr "_Set 沒有收到任何值!\\n" msgid "Nobody" msgstr "沒有人" -#: lib/RT/Interface/Web.pm:900 x:903 +#: lib/RT/Interface/Web.pm:960 msgid "Nonexistant field?" msgstr "欄ä½ä¸å˜åœ¨ï¼Ÿ" @@ -3843,7 +3987,7 @@ msgstr "尚未完工。" msgid "Not yet implemented...." msgstr "尚未完工..." -#: html/Approvals/Elements/Approve:48 html/Work/Tickets/Create.html:143 +#: html/Approvals/Elements/Approve:48 html/Work/Tickets/Elements/AddContent:9 msgid "Notes" msgstr "備註" @@ -3851,67 +3995,67 @@ msgstr "備註" msgid "Notes:" msgstr "備註:" -#: lib/RT/User_Overlay.pm:767 +#: lib/RT/User_Overlay.pm:772 msgid "Notification could not be sent" msgstr "無法é€å‡ºé€šçŸ¥" -#: etc/initialdata.zh:111 etc/initialdata:93 +#: etc/initialdata:93 msgid "Notify AdminCcs" msgstr "通知管ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:107 etc/initialdata:89 +#: etc/initialdata:89 msgid "Notify AdminCcs as Comment" msgstr "以評論方å¼é€šçŸ¥ç®¡ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:138 etc/initialdata:120 +#: etc/initialdata:120 msgid "Notify Other Recipients" msgstr "通知其他收件人" -#: etc/initialdata.zh:134 etc/initialdata:116 +#: etc/initialdata:116 msgid "Notify Other Recipients as Comment" msgstr "以評論方å¼é€šçŸ¥å…¶ä»–收件人" -#: etc/initialdata.zh:103 etc/initialdata:85 +#: etc/initialdata:85 msgid "Notify Owner" msgstr "通知承辦人" -#: etc/initialdata.zh:99 etc/initialdata:81 +#: etc/initialdata:81 msgid "Notify Owner as Comment" msgstr "以評論方å¼é€šçŸ¥æ‰¿è¾¦äºº" -#: etc/initialdata.zh:385 etc/initialdata:361 +#: etc/initialdata:361 msgid "Notify Owner of their rejected ticket" msgstr "通知承辦人申請單已é§å›ž" -#: etc/initialdata.zh:374 etc/initialdata:350 +#: etc/initialdata:350 msgid "Notify Owner of their ticket has been approved by all approvers" msgstr "通知承辦人申請單已完æˆå…¨éƒ¨ç°½æ ¸" -#: etc/initialdata.zh:359 etc/initialdata:338 +#: etc/initialdata:338 msgid "Notify Owner of their ticket has been approved by some approver" msgstr "通知承辦人申請單已完æˆæŸé …ç°½æ ¸" -#: etc/initialdata.zh:343 etc/initialdata:319 etc/upgrade/2.1.71:17 html/Edit/Elements/CreateApprovalsQueue:22 +#: etc/initialdata:319 etc/upgrade/2.1.71:17 html/Edit/Elements/CreateApprovalsQueue:22 msgid "Notify Owners and AdminCcs of new items pending their approval" msgstr "æ•´ç†å¾…ç°½æ ¸äº‹é …ï¼Œé€šçŸ¥æ‰¿è¾¦äººåŠç®¡ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:95 etc/initialdata:77 +#: etc/initialdata:77 msgid "Notify Requestors" msgstr "通知申請人" -#: etc/initialdata.zh:121 etc/initialdata:103 +#: etc/initialdata:103 msgid "Notify Requestors and Ccs" msgstr "通知申請人åŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:116 etc/initialdata:98 +#: etc/initialdata:98 msgid "Notify Requestors and Ccs as Comment" msgstr "以評論方å¼é€šçŸ¥ç”³è«‹äººåŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:130 etc/initialdata:112 +#: etc/initialdata:112 msgid "Notify Requestors, Ccs and AdminCcs" msgstr "通知申請人ã€å‰¯æœ¬åŠç®¡ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:126 etc/initialdata:108 +#: etc/initialdata:108 msgid "Notify Requestors, Ccs and AdminCcs as Comment" msgstr "以評論方å¼é€šçŸ¥ç”³è«‹äººã€å‰¯æœ¬åŠç®¡ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" @@ -3931,9 +4075,9 @@ msgstr "11" msgid "November" msgstr "å一月" -#: html/Edit/Global/Basic/Top:74 +#: html/Edit/Global/Basic/Top:83 msgid "OIN104" -msgstr "é…åˆ 104eHRMS 介é¢" +msgstr "104eHRMS 介é¢" #: html/Edit/Global/Workflow/Export.html:30 html/Work/Copyright.html:23 msgid "OK" @@ -3947,7 +4091,7 @@ msgstr "無法新增物件" msgid "Object created" msgstr "物件新增完畢" -#: html/Edit/Users/Info:35 +#: NOT FOUND IN SOURCE msgid "Occupation Status" msgstr "在è·ç‹€æ…‹" @@ -3963,7 +4107,7 @@ msgstr "10" msgid "October" msgstr "å月" -#: html/Edit/Users/Info:32 +#: NOT FOUND IN SOURCE msgid "Office Phone" msgstr "辦公室電話" @@ -3971,35 +4115,39 @@ msgstr "辦公室電話" msgid "On" msgstr "ç‰æ–¼" -#: etc/initialdata.zh:173 etc/initialdata:155 +#: html/Edit/Global/CustomField/Top:68 +msgid "On Change" +msgstr "更改申請單時" + +#: etc/initialdata:155 msgid "On Comment" msgstr "評論時" -#: etc/initialdata.zh:166 etc/initialdata:148 +#: etc/initialdata:148 msgid "On Correspond" msgstr "回覆申請單時" -#: etc/initialdata.zh:155 etc/initialdata:137 +#: etc/initialdata:137 html/Edit/Global/CustomField/Top:57 msgid "On Create" msgstr "新增申請單時" -#: etc/initialdata.zh:187 etc/initialdata:169 +#: etc/initialdata:169 msgid "On Owner Change" msgstr "承辦人改變時" -#: etc/initialdata.zh:195 etc/initialdata:177 +#: etc/initialdata:177 msgid "On Queue Change" msgstr "表單改變時" -#: etc/initialdata.zh:201 etc/initialdata:183 +#: etc/initialdata:183 msgid "On Resolve" msgstr "解決申請單時" -#: etc/initialdata.zh:179 etc/initialdata:161 +#: etc/initialdata:161 msgid "On Status Change" msgstr "ç¾æ³æ”¹è®Šæ™‚" -#: etc/initialdata.zh:160 etc/initialdata:142 +#: etc/initialdata:142 msgid "On Transaction" msgstr "發生更動時" @@ -4013,7 +4161,7 @@ msgstr "僅顯示 %1 之後新增的申請單" msgid "Only show approvals for requests created before %1" msgstr "僅顯示 %1 之å‰æ–°å¢žçš„申請單" -#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:18 html/Edit/Queues/Basic/Top:69 html/Edit/Queues/List:13 html/Elements/Quicksearch:30 html/Work/Delegates/Info:48 html/Work/Delegates/Info:51 html/Work/Delegates/List:12 html/Work/Elements/Quicksearch:16 html/Work/Overview/Info:41 html/Work/Tickets/Display.html:28 +#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:18 html/Edit/Queues/Basic/Top:68 html/Edit/Queues/List:15 html/Edit/Queues/List:27 html/Elements/Quicksearch:30 html/Work/Delegates/Info:48 html/Work/Delegates/Info:51 html/Work/Delegates/List:12 html/Work/Elements/Quicksearch:16 html/Work/Overview/Info:41 html/Work/Tickets/Display.html:51 msgid "Open" msgstr "é–‹å•Ÿ" @@ -4033,7 +4181,7 @@ msgstr "在新視窗開啟(列表的)申請單" msgid "Open tickets (from listing) in another window" msgstr "在å¦ä¸€å€‹è¦–窗開啟(列表的)申請單" -#: etc/initialdata.zh:150 etc/initialdata:132 +#: etc/initialdata:132 msgid "Open tickets on correspondence" msgstr "收到回覆時å³é–‹å•Ÿç”³è«‹å–®" @@ -4053,11 +4201,11 @@ msgstr "é¸é …æè¿°" msgid "Option Name" msgstr "é¸é …å稱" -#: html/Search/Elements/PickRestriction:100 html/Work/Search/PickRestriction:81 +#: html/Search/Elements/PickRestriction:100 html/Work/Search/PickRestriction:87 msgid "Ordering and sorting" msgstr "é †åºèˆ‡æŽ’åºæ–¹å¼" -#: html/Admin/Elements/ModifyUser:45 html/Admin/Users/Modify.html:116 html/Edit/Global/Basic/Top:50 html/Elements/SelectUsers:28 html/User/Prefs.html:85 html/Work/Preferences/Info:75 +#: html/Admin/Elements/ModifyUser:45 html/Admin/Users/Modify.html:116 html/Edit/Elements/SelectUsers:7 html/Edit/Global/Basic/Top:55 html/Elements/SelectUsers:28 html/User/Prefs.html:110 html/Work/Preferences/Info:77 msgid "Organization" msgstr "組織å稱" @@ -4070,11 +4218,11 @@ msgstr "組織:" msgid "Originating ticket: #%1" msgstr "原申請單:#%1" -#: html/Edit/Elements/PickUsers:109 html/Edit/Users/Add.html:106 html/Work/Tickets/Cc:80 +#: html/Edit/Elements/PickUsers:111 html/Edit/Users/Add.html:106 html/Work/Tickets/Cc:80 msgid "Other comma-delimited email addresses" msgstr "其他e-mail帳號 (僅e-mail通知;多ç†å¸³è™Ÿè«‹ç”¨é€—號','å€éš”)" -#: html/Admin/Elements/ModifyQueue:54 html/Admin/Queues/Modify.html:68 html/Edit/Queues/Basic/Top:41 +#: html/Admin/Elements/ModifyQueue:54 html/Admin/Queues/Modify.html:68 html/Edit/Queues/Basic/Top:44 msgid "Over time, priority moves toward" msgstr "å„ªå…ˆé †ä½éš¨æ™‚é–“å¢žåŠ èª¿æ•´ç‚º" @@ -4086,7 +4234,7 @@ msgstr "以 %1 表單的自訂欄ä½å–代ç¾æœ‰æ¬„ä½" msgid "Override global rights" msgstr "å–代全域權é™" -#: html/Admin/Elements/CheckOverrideGlobalACL:34 +#: html/Admin/Elements/CheckOverrideGlobalACL:36 #. (loc_fuzzy($msg)) msgid "OverrideGlobalACL status %1" msgstr "å–ä»£å…¨åŸŸæ¬Šé™ %1" @@ -4103,7 +4251,7 @@ msgstr "承辦申請單" msgid "OwnTicket" msgstr "承辦申請單" -#: etc/initialdata.zh:56 etc/initialdata:38 html/Admin/Elements/ModifyTemplateAsWorkflow:141 html/Edit/Global/Workflow/Owner.html:19 html/Edit/Queues/Basic/Top:47 html/Edit/Queues/Basic/Top:58 html/Elements/MyRequests:31 html/SelfService/Elements/MyRequests:29 html/Ticket/Create.html:47 html/Ticket/Elements/EditPeople:42 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/ShowPeople:26 html/Ticket/Update.html:62 html/Work/Elements/MyRequests:19 html/Work/Elements/Quicksearch:18 html/Work/Tickets/Elements/ShowBasics:21 html/Work/Tickets/Update.html:27 lib/RT/ACE_Overlay.pm:85 lib/RT/Tickets_Overlay.pm:1244 +#: etc/initialdata:38 html/Admin/Elements/ModifyTemplateAsWorkflow:141 html/Edit/Global/Workflow/Owner.html:19 html/Edit/Queues/Basic/Top:51 html/Edit/Queues/Basic/Top:59 html/Elements/MyRequests:31 html/SelfService/Elements/MyRequests:29 html/Ticket/Create.html:47 html/Ticket/Elements/EditPeople:42 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/ShowPeople:26 html/Ticket/Update.html:62 html/Work/Elements/MyRequests:19 html/Work/Elements/Quicksearch:18 html/Work/Tickets/Elements/EditPeople:28 html/Work/Tickets/Elements/ShowBasics:21 html/Work/Tickets/Update.html:27 lib/RT/ACE_Overlay.pm:85 lib/RT/Tickets_Overlay.pm:1263 msgid "Owner" msgstr "承辦人" @@ -4111,7 +4259,7 @@ msgstr "承辦人" msgid "Owner changed from %1 to %2" msgstr "承辦人已從 %1 改為 %2" -#: lib/RT/Transaction_Overlay.pm:582 +#: lib/RT/Transaction_Overlay.pm:539 #. ($Old->Name , $New->Name) msgid "Owner forcibly changed from %1 to %2" msgstr "強制將承辦人從 %1 改為 %2" @@ -4120,15 +4268,15 @@ msgstr "強制將承辦人從 %1 改為 %2" msgid "Owner is" msgstr "承辦人" -#: html/Work/Elements/List:27 html/Work/Queues/List:8 html/Work/Tickets/Create.html:56 html/Work/Tickets/Elements/ShowBasics:60 +#: html/Work/Elements/List:27 html/Work/Queues/List:8 html/Work/Tickets/Create.html:55 html/Work/Tickets/Elements/ShowBasics:60 msgid "Owner's Phone" msgstr "承辦人電話" -#: html/Edit/Elements/Page:39 -msgid "Page" +#: html/Edit/Elements/Page:40 +msgid "Page #" msgstr " " -#: html/Admin/Users/Modify.html:173 html/User/Prefs.html:55 html/Work/Preferences/Info:38 +#: html/Admin/Users/Modify.html:173 html/User/Prefs.html:75 html/Work/Preferences/Info:40 msgid "Pager" msgstr "呼å«å™¨" @@ -4136,7 +4284,7 @@ msgstr "呼å«å™¨" msgid "PagerPhone" msgstr "呼å«å™¨è™Ÿç¢¼" -#: html/Edit/Global/Workflow/Action:81 html/Edit/Global/Workflow/Condition:66 +#: html/Edit/Global/Workflow/Action:75 html/Edit/Global/Workflow/Condition:65 msgid "Parameter" msgstr "呼å«åƒæ•¸" @@ -4144,7 +4292,7 @@ msgstr "呼å«åƒæ•¸" msgid "Parent" msgstr "上級" -#: html/Ticket/Create.html:181 html/Ticket/Elements/BulkLinks:38 html/Ticket/Elements/EditLinks:126 html/Ticket/Elements/EditLinks:57 html/Ticket/Elements/ShowLinks:46 html/Work/Search/BulkLinks:14 +#: html/Ticket/Create.html:182 html/Ticket/Elements/BulkLinks:38 html/Ticket/Elements/EditLinks:109 html/Ticket/Elements/EditLinks:54 html/Ticket/Elements/ShowLinks:46 html/Work/Search/BulkLinks:14 html/Work/Tickets/Elements/EditLinks:113 html/Work/Tickets/Elements/EditLinks:45 html/Work/Tickets/Elements/ShowLinks:26 msgid "Parents" msgstr "æ¯ç”³è«‹å–®" @@ -4152,7 +4300,7 @@ msgstr "æ¯ç”³è«‹å–®" msgid "Park Space" msgstr "åœè»Šä½ç”³è«‹" -#: html/Elements/Login:52 html/User/Prefs.html:60 html/Work/Preferences/Info:44 +#: html/Elements/Login:52 html/User/Prefs.html:83 html/Work/Preferences/Info:46 msgid "Password" msgstr "密碼" @@ -4160,20 +4308,20 @@ msgstr "密碼" msgid "Password Reminder" msgstr "密碼æ示" -#: lib/RT/User_Overlay.pm:228 lib/RT/User_Overlay.pm:985 +#: lib/RT/User_Overlay.pm:230 lib/RT/User_Overlay.pm:990 msgid "Password too short" msgstr "密碼太çŸ" -#: html/Admin/Users/Modify.html:290 html/User/Prefs.html:171 html/Work/Preferences/Info:167 +#: html/Admin/Users/Modify.html:292 html/User/Prefs.html:209 html/Work/Preferences/Info:173 #. (loc_fuzzy($msg)) msgid "Password: %1" msgstr "密碼:%1" -#: html/Admin/Users/Modify.html:292 +#: html/Admin/Users/Modify.html:294 msgid "Passwords do not match." msgstr "密碼確èªå¤±æ•—。" -#: html/User/Prefs.html:173 html/Work/Preferences/Info:169 +#: html/User/Prefs.html:211 html/Work/Preferences/Info:175 msgid "Passwords do not match. Your password has not been changed" msgstr "密碼確èªå¤±æ•—。您的密碼並未改變。" @@ -4193,11 +4341,11 @@ msgstr "人員" msgid "People with Queue Rights" msgstr "æ“有表單權é™äººå“¡" -#: etc/initialdata.zh:143 etc/initialdata:125 +#: etc/initialdata:125 msgid "Perform a user-defined action" msgstr "執行使用者自訂的動作" -#: lib/RT/ACE_Overlay.pm:230 lib/RT/ACE_Overlay.pm:236 lib/RT/ACE_Overlay.pm:562 lib/RT/ACE_Overlay.pm:572 lib/RT/ACE_Overlay.pm:582 lib/RT/ACE_Overlay.pm:647 lib/RT/CurrentUser.pm:82 lib/RT/CurrentUser.pm:91 lib/RT/CustomField_Overlay.pm:100 lib/RT/CustomField_Overlay.pm:201 lib/RT/CustomField_Overlay.pm:233 lib/RT/CustomField_Overlay.pm:510 lib/RT/CustomField_Overlay.pm:90 lib/RT/Group_Overlay.pm:1094 lib/RT/Group_Overlay.pm:1098 lib/RT/Group_Overlay.pm:1107 lib/RT/Group_Overlay.pm:1158 lib/RT/Group_Overlay.pm:1162 lib/RT/Group_Overlay.pm:1168 lib/RT/Group_Overlay.pm:425 lib/RT/Group_Overlay.pm:517 lib/RT/Group_Overlay.pm:595 lib/RT/Group_Overlay.pm:603 lib/RT/Group_Overlay.pm:700 lib/RT/Group_Overlay.pm:704 lib/RT/Group_Overlay.pm:710 lib/RT/Group_Overlay.pm:903 lib/RT/Group_Overlay.pm:907 lib/RT/Group_Overlay.pm:920 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:125 lib/RT/Scrip_Overlay.pm:136 lib/RT/Scrip_Overlay.pm:196 lib/RT/Scrip_Overlay.pm:433 lib/RT/Template_Overlay.pm:283 lib/RT/Template_Overlay.pm:87 lib/RT/Template_Overlay.pm:93 lib/RT/Ticket_Overlay.pm:1359 lib/RT/Ticket_Overlay.pm:1369 lib/RT/Ticket_Overlay.pm:1383 lib/RT/Ticket_Overlay.pm:1517 lib/RT/Ticket_Overlay.pm:1526 lib/RT/Ticket_Overlay.pm:1539 lib/RT/Ticket_Overlay.pm:1888 lib/RT/Ticket_Overlay.pm:2026 lib/RT/Ticket_Overlay.pm:2190 lib/RT/Ticket_Overlay.pm:2257 lib/RT/Ticket_Overlay.pm:2616 lib/RT/Ticket_Overlay.pm:2688 lib/RT/Ticket_Overlay.pm:2782 lib/RT/Ticket_Overlay.pm:2797 lib/RT/Ticket_Overlay.pm:2996 lib/RT/Ticket_Overlay.pm:3006 lib/RT/Ticket_Overlay.pm:3011 lib/RT/Ticket_Overlay.pm:3233 lib/RT/Ticket_Overlay.pm:3431 lib/RT/Ticket_Overlay.pm:3593 lib/RT/Ticket_Overlay.pm:3645 lib/RT/Ticket_Overlay.pm:3823 lib/RT/Transaction_Overlay.pm:466 lib/RT/Transaction_Overlay.pm:473 lib/RT/Transaction_Overlay.pm:502 lib/RT/Transaction_Overlay.pm:509 lib/RT/User_Overlay.pm:1079 lib/RT/User_Overlay.pm:1527 lib/RT/User_Overlay.pm:687 lib/RT/User_Overlay.pm:722 lib/RT/User_Overlay.pm:978 +#: lib/RT/ACE_Overlay.pm:230 lib/RT/ACE_Overlay.pm:236 lib/RT/ACE_Overlay.pm:562 lib/RT/ACE_Overlay.pm:572 lib/RT/ACE_Overlay.pm:582 lib/RT/ACE_Overlay.pm:647 lib/RT/CurrentUser.pm:82 lib/RT/CurrentUser.pm:91 lib/RT/CustomField_Overlay.pm:100 lib/RT/CustomField_Overlay.pm:201 lib/RT/CustomField_Overlay.pm:233 lib/RT/CustomField_Overlay.pm:511 lib/RT/CustomField_Overlay.pm:90 lib/RT/Group_Overlay.pm:1096 lib/RT/Group_Overlay.pm:1100 lib/RT/Group_Overlay.pm:1109 lib/RT/Group_Overlay.pm:1160 lib/RT/Group_Overlay.pm:1164 lib/RT/Group_Overlay.pm:1170 lib/RT/Group_Overlay.pm:423 lib/RT/Group_Overlay.pm:515 lib/RT/Group_Overlay.pm:593 lib/RT/Group_Overlay.pm:601 lib/RT/Group_Overlay.pm:698 lib/RT/Group_Overlay.pm:702 lib/RT/Group_Overlay.pm:708 lib/RT/Group_Overlay.pm:901 lib/RT/Group_Overlay.pm:905 lib/RT/Group_Overlay.pm:918 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:934 lib/RT/Scrip_Overlay.pm:125 lib/RT/Scrip_Overlay.pm:136 lib/RT/Scrip_Overlay.pm:201 lib/RT/Scrip_Overlay.pm:441 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:87 lib/RT/Template_Overlay.pm:93 lib/RT/Ticket_Overlay.pm:1386 lib/RT/Ticket_Overlay.pm:1396 lib/RT/Ticket_Overlay.pm:1410 lib/RT/Ticket_Overlay.pm:1544 lib/RT/Ticket_Overlay.pm:1553 lib/RT/Ticket_Overlay.pm:1566 lib/RT/Ticket_Overlay.pm:1915 lib/RT/Ticket_Overlay.pm:2053 lib/RT/Ticket_Overlay.pm:2217 lib/RT/Ticket_Overlay.pm:2286 lib/RT/Ticket_Overlay.pm:2647 lib/RT/Ticket_Overlay.pm:2728 lib/RT/Ticket_Overlay.pm:2832 lib/RT/Ticket_Overlay.pm:2847 lib/RT/Ticket_Overlay.pm:3046 lib/RT/Ticket_Overlay.pm:3056 lib/RT/Ticket_Overlay.pm:3061 lib/RT/Ticket_Overlay.pm:3284 lib/RT/Ticket_Overlay.pm:3288 lib/RT/Ticket_Overlay.pm:3487 lib/RT/Ticket_Overlay.pm:3649 lib/RT/Ticket_Overlay.pm:3701 lib/RT/Ticket_Overlay.pm:3907 lib/RT/Transaction_Overlay.pm:415 lib/RT/Transaction_Overlay.pm:422 lib/RT/Transaction_Overlay.pm:451 lib/RT/Transaction_Overlay.pm:458 lib/RT/User_Overlay.pm:1084 lib/RT/User_Overlay.pm:1532 lib/RT/User_Overlay.pm:692 lib/RT/User_Overlay.pm:727 lib/RT/User_Overlay.pm:983 msgid "Permission Denied" msgstr "權é™ä¸è¶³" @@ -4234,6 +4382,22 @@ msgid "PersonalHomepage" msgstr "個人首é " #: NOT FOUND IN SOURCE +msgid "Phase 1: Create/Rename Groups (%1)" +msgstr "第一階段:群組建立åŠæ”¹å (%1)" + +#: NOT FOUND IN SOURCE +msgid "Phase 2: Disable/Enable Groups (%1)" +msgstr "第二階段:群組åœç”¨åŠå•Ÿç”¨ (%1)" + +#: NOT FOUND IN SOURCE +msgid "Phase 3: Create/Rename Users (%1)" +msgstr "第三階段:使用者建立åŠæ”¹å (%1)" + +#: NOT FOUND IN SOURCE +msgid "Phase 4: Disable/Enable Users (%1)" +msgstr "第四階段:使用者åœç”¨åŠå•Ÿç”¨ (%1)" + +#: NOT FOUND IN SOURCE msgid "Phone" msgstr "電話" @@ -4241,11 +4405,11 @@ msgstr "電話" msgid "Phone number" msgstr "電話號碼" -#: html/Admin/Users/Modify.html:155 html/User/Prefs.html:48 html/Work/Preferences/Info:30 +#: html/Admin/Users/Modify.html:155 html/User/Prefs.html:60 html/Work/Preferences/Info:32 msgid "Phone numbers" msgstr "電話號碼" -#: html/Edit/Users/Add.html:3 html/Work/Delegates/Add.html:3 html/Work/Delegates/Info:34 html/Work/Tickets/ModifyPeople.html:2 +#: html/Edit/Queues/Basic/Add.html:3 html/Edit/Queues/Basic/Top:55 html/Edit/Users/Add.html:3 html/Work/Delegates/Add.html:3 html/Work/Delegates/Info:34 html/Work/Tickets/ModifyPeople.html:2 msgid "Pick" msgstr "挑é¸" @@ -4257,7 +4421,7 @@ msgstr "出發地點" msgid "Placeholder" msgstr "尚未完工" -#: html/Edit/Elements/PickUsers:31 html/Edit/Elements/PickUsers:44 html/Edit/Elements/SelectCustomFieldType:3 html/Work/Elements/SelectOwner:3 html/Work/Tickets/Elements/EditCustomField:183 html/Work/Tickets/Elements/EditCustomField:75 html/Work/Tickets/Elements/EditCustomFieldEntries:81 html/Work/Tickets/Elements/EditCustomFieldEntries:88 +#: html/Edit/Elements/PickUsers:31 html/Edit/Elements/PickUsers:44 html/Edit/Elements/SelectCustomFieldType:3 html/Work/Elements/SelectOwner:3 html/Work/Tickets/Elements/EditCustomField:187 html/Work/Tickets/Elements/EditCustomFieldEntry:24 html/Work/Tickets/Elements/EditCustomFieldEntry:35 msgid "Please Select" msgstr "è«‹é¸æ“‡" @@ -4274,6 +4438,10 @@ msgid "Please select a queue's workflow" msgstr "è«‹é¸æ“‡è¡¨å–®æµç¨‹" #: NOT FOUND IN SOURCE +msgid "Please select one of the category types above." +msgstr "請從上é¢é¸æ“‡ä¸€é …分類。" + +#: NOT FOUND IN SOURCE msgid "Please select role" msgstr "è«‹é¸æ“‡è§’色" @@ -4285,19 +4453,19 @@ msgstr "經營è¦ç« " msgid "Position" msgstr "è·å‹™" -#: html/Edit/Users/Info:42 +#: NOT FOUND IN SOURCE msgid "Position Level" msgstr "è·ç‰" -#: html/Edit/Elements/PickUsers:41 html/Edit/Global/UserRight/List:13 html/Edit/Global/UserRight/Top:23 html/Edit/Users/Add.html:41 html/Edit/Users/List:11 html/Edit/Users/Top:22 html/Work/Delegates/Add.html:26 html/Work/Delegates/Info:84 html/Work/Overview/Info:66 +#: html/Edit/Elements/PickUsers:41 html/Edit/Global/UserRight/List:13 html/Edit/Global/UserRight/Top:23 html/Edit/Queues/Basic/Add.html:26 html/Edit/Users/Add.html:41 html/Work/Delegates/Add.html:26 html/Work/Delegates/Info:84 html/Work/Overview/Info:66 msgid "Position Name" msgstr "è·å‹™å稱" -#: html/Edit/Global/UserRight/List:14 html/Edit/Global/UserRight/Top:33 html/Edit/Users/List:12 html/Edit/Users/Top:32 +#: html/Edit/Global/UserRight/List:14 html/Edit/Global/UserRight/Top:33 msgid "Position Number" msgstr "è·å‹™ä»£ç¢¼" -#: html/Edit/Users/Info:43 +#: NOT FOUND IN SOURCE msgid "Position Rank" msgstr "è·ç´š" @@ -4334,7 +4502,7 @@ msgstr "å„ªå…ˆé †ä½" msgid "Principal %1 not found." msgstr "找ä¸åˆ°å–®ä½ %1。" -#: html/Search/Elements/PickRestriction:53 html/Ticket/Create.html:153 html/Ticket/Elements/EditBasics:53 html/Ticket/Elements/ShowBasics:38 html/Work/Search/PickRestriction:34 lib/RT/Tickets_Overlay.pm:1042 +#: html/Search/Elements/PickRestriction:53 html/Ticket/Create.html:153 html/Ticket/Elements/EditBasics:53 html/Ticket/Elements/ShowBasics:38 html/Work/Search/PickRestriction:34 html/Work/Tickets/Elements/EditBasics:41 lib/RT/Tickets_Overlay.pm:1061 msgid "Priority" msgstr "å„ªå…ˆé †ä½" @@ -4342,11 +4510,11 @@ msgstr "å„ªå…ˆé †ä½" msgid "Priority starts at" msgstr "å„ªå…ˆé †ä½èµ·å§‹å€¼" -#: etc/initialdata.zh:43 etc/initialdata:25 +#: etc/initialdata:25 msgid "Privileged" msgstr "內部æˆå“¡" -#: html/Admin/Users/Modify.html:270 html/User/Prefs.html:162 html/Work/Preferences/Info:158 +#: html/Admin/Users/Modify.html:272 html/User/Prefs.html:200 html/Work/Preferences/Info:164 #. (loc_fuzzy($msg)) msgid "Privileged status: %1" msgstr "內部æˆå“¡ç‹€æ…‹ï¼š%1" @@ -4359,11 +4527,19 @@ msgstr "內部æˆå“¡" msgid "Process Status" msgstr "處ç†ç‹€æ…‹" -#: etc/initialdata.zh:41 etc/initialdata.zh:47 etc/initialdata.zh:53 etc/initialdata.zh:77 etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59 +#: html/Edit/Queues/List:10 +msgid "Project Name" +msgstr "專案å稱" + +#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59 msgid "Pseudogroup for internal use" msgstr "內部用的虛擬群組" -#: html/Work/Preferences/Info:68 +#: html/Edit/Queues/List:11 +msgid "Public Description" +msgstr "公開說明" + +#: html/Work/Preferences/Info:70 msgid "Public Info" msgstr "公開資訊" @@ -4371,11 +4547,15 @@ msgstr "公開資訊" msgid "Public Service" msgstr "公共事務å€" +#: NOT FOUND IN SOURCE +msgid "Purging stale data: %1" +msgstr "移除éŽæœŸè³‡æ–™: %1" + #: html/Edit/Users/Search.html:4 msgid "Query" msgstr "查詢" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:166 html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Elements/Quicksearch:28 html/Search/Elements/PickRestriction:45 html/SelfService/Create.html:32 html/Ticket/Create.html:37 html/Ticket/Elements/EditBasics:63 html/Ticket/Elements/ShowBasics:42 html/User/Elements/DelegateRights:79 html/Work/Elements/MyApprovals:10 html/Work/Elements/MyRequests:17 html/Work/Elements/MyTickets:17 html/Work/Elements/Quicksearch:14 html/Work/Search/PickRestriction:26 lib/RT/Tickets_Overlay.pm:883 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:166 html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Elements/Quicksearch:28 html/Search/Elements/PickRestriction:45 html/SelfService/Create.html:32 html/Ticket/Create.html:37 html/Ticket/Elements/EditBasics:63 html/Ticket/Elements/ShowBasics:42 html/User/Elements/DelegateRights:79 html/Work/Elements/MyApprovals:10 html/Work/Elements/MyRequests:17 html/Work/Elements/MyTickets:17 html/Work/Elements/Quicksearch:14 html/Work/Search/PickRestriction:26 html/Work/Tickets/Elements/EditBasics:16 lib/RT/Tickets_Overlay.pm:902 msgid "Queue" msgstr "表單" @@ -4393,19 +4573,19 @@ msgstr "找ä¸åˆ°è¡¨å–® '%1'\\n" msgid "Queue Keyword Selections" msgstr "表單關éµå—é¸å–" -#: html/Admin/Elements/ModifyQueue:30 html/Admin/Queues/Modify.html:42 html/Edit/Queues/Basic/Top:12 html/Edit/Queues/Basic/index.html:36 html/Edit/Queues/Global:21 html/Edit/Queues/List:6 html/Edit/Users/Queue:10 html/Work/Delegates/List:6 html/Work/Elements/List:11 html/Work/Queues/List:5 html/Work/Tickets/Create.html:22 html/Work/Tickets/Elements/ShowBasics:6 +#: html/Admin/Elements/ModifyQueue:30 html/Admin/Queues/Modify.html:42 html/Edit/Queues/Basic/Top:13 html/Edit/Queues/Basic/index.html:36 html/Edit/Queues/Global:21 html/Edit/Queues/List:20 html/Edit/Users/Queue:10 html/Work/Delegates/List:6 html/Work/Elements/List:11 html/Work/Queues/List:5 html/Work/Tickets/Create.html:21 html/Work/Tickets/Elements/ShowBasics:6 msgid "Queue Name" msgstr "表單å稱" -#: html/Edit/Queues/List:8 html/Work/Elements/List:25 html/Work/Queues/List:7 html/Work/Tickets/Create.html:35 html/Work/Tickets/Elements/ShowBasics:19 +#: html/Edit/Queues/List:22 html/Work/Elements/List:25 html/Work/Queues/List:7 html/Work/Tickets/Create.html:34 html/Work/Tickets/Elements/ShowBasics:19 msgid "Queue Owner" msgstr "æ¥å‹™æ‰¿è¾¦äºº" -#: html/Edit/Queues/Basic/Top:35 +#: html/Edit/Queues/Basic/Top:38 msgid "Queue Priority" msgstr "優先ç‰ç´š" -#: html/Edit/Global/GroupRight/Top:24 html/Edit/Global/UserRight/Top:43 html/Edit/Users/Queue:11 html/Edit/Users/index.html:124 +#: html/Edit/Global/GroupRight/Top:24 html/Edit/Global/UserRight/Top:43 html/Edit/Users/Queue:11 html/Edit/Users/index.html:97 msgid "Queue Rights" msgstr "表單權é™" @@ -4425,11 +4605,11 @@ msgstr "表單已å˜åœ¨" msgid "Queue could not be created" msgstr "無法新增表單" -#: html/Edit/Queues/autohandler:8 html/Ticket/Create.html:204 html/Work/Tickets/Create.html:185 +#: html/Edit/Queues/autohandler:8 html/Ticket/Create.html:208 html/Work/Tickets/Create.html:180 msgid "Queue could not be loaded." msgstr "無法載入表單" -#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:283 +#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:283 lib/RT/StyleGuide.pod:789 msgid "Queue created" msgstr "表單新增完畢" @@ -4458,7 +4638,7 @@ msgstr "表單一覽" msgid "RT %1" msgstr "RT %1" -#: docs/design_docs/string-extraction-guide.txt:70 +#: docs/design_docs/string-extraction-guide.txt:70 lib/RT/StyleGuide.pod:776 #. ($RT::VERSION, $RT::rtname) msgid "RT %1 for %2" msgstr "%2:RT %1 版" @@ -4574,11 +4754,15 @@ msgstr "系統é‹è¡Œè§’色" msgid "RT::Ticket-Role" msgstr "申請單é‹è¡Œè§’色" -#: html/Work/Tickets/Elements/ShowTransaction:11 +#: html/Work/Tickets/Elements/ShowTransaction:14 msgid "RT_System" msgstr "系統訊æ¯" -#: html/Admin/Users/Modify.html:57 html/Admin/Users/Prefs.html:51 html/User/Prefs.html:43 html/Work/Preferences/Info:18 +#: html/Edit/Global/CustomField/SelectWritable:7 +msgid "Read Only" +msgstr "唯讀" + +#: html/Admin/Users/Modify.html:57 html/Admin/Users/Prefs.html:51 html/Edit/Elements/SelectUsers:5 html/Edit/Users/List:6 html/User/Prefs.html:47 html/Work/Preferences/Info:18 msgid "Real Name" msgstr "真實姓å" @@ -4586,15 +4770,35 @@ msgstr "真實姓å" msgid "RealName" msgstr "真實姓å" -#: html/Work/Approvals/Display.html:27 html/Work/Tickets/Update.html:85 +#: html/Work/Approvals/Display.html:30 html/Work/Tickets/Update.html:81 msgid "Really reject this ticket?" msgstr "您確定è¦é§å›žé€™å¼µç”³è«‹å–®å—Žï¼Ÿ" -#: html/Ticket/Create.html:184 html/Ticket/Elements/BulkLinks:50 html/Ticket/Elements/EditLinks:138 html/Ticket/Elements/EditLinks:93 html/Ticket/Elements/ShowLinks:70 html/Work/Search/BulkLinks:26 +#: lib/RT/Transaction_Overlay.pm:592 +#. ($value) +msgid "Reference by %1 added" +msgstr "å·²åŠ å…¥ %1 為åƒè€ƒæœ¬ç”³è«‹å–®" + +#: lib/RT/Transaction_Overlay.pm:629 +#. ($value) +msgid "Reference by %1 deleted" +msgstr "已移除 %1 為åƒè€ƒæœ¬ç”³è«‹å–®" + +#: lib/RT/Transaction_Overlay.pm:589 +#. ($value) +msgid "Reference to %1 added" +msgstr "å·²åŠ å…¥åƒè€ƒç”³è«‹å–® %1" + +#: lib/RT/Transaction_Overlay.pm:626 +#. ($value) +msgid "Reference to %1 deleted" +msgstr "已移除åƒè€ƒç”³è«‹å–® %1" + +#: html/Ticket/Create.html:185 html/Ticket/Elements/BulkLinks:50 html/Ticket/Elements/EditLinks:121 html/Ticket/Elements/EditLinks:81 html/Ticket/Elements/ShowLinks:70 html/Work/Search/BulkLinks:26 html/Work/Tickets/Elements/EditLinks:125 html/Work/Tickets/Elements/EditLinks:81 html/Work/Tickets/Elements/ShowLinks:38 msgid "Referred to by" msgstr "被åƒè€ƒ" -#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:183 html/Ticket/Elements/BulkLinks:46 html/Ticket/Elements/EditLinks:134 html/Ticket/Elements/EditLinks:79 html/Ticket/Elements/ShowLinks:60 html/Work/Search/BulkLinks:22 +#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:184 html/Ticket/Elements/BulkLinks:46 html/Ticket/Elements/EditLinks:117 html/Ticket/Elements/EditLinks:72 html/Ticket/Elements/ShowLinks:60 html/Work/Search/BulkLinks:22 html/Work/Tickets/Elements/EditLinks:121 html/Work/Tickets/Elements/EditLinks:67 html/Work/Tickets/Elements/ShowLinks:33 msgid "Refers to" msgstr "åƒè€ƒ" @@ -4619,7 +4823,7 @@ msgstr "æ›´æ–°" msgid "Refresh this page every %1 minutes." msgstr "æ¯ %1 分é˜æ›´æ–°é é¢" -#: html/Ticket/Create.html:173 html/Ticket/Elements/ShowSummary:61 html/Ticket/ModifyAll.html:56 +#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:61 html/Ticket/ModifyAll.html:56 msgid "Relationships" msgstr "關係" @@ -4639,7 +4843,7 @@ msgstr "移除副本" msgid "Remove Requestor" msgstr "移除申請人" -#: html/Ticket/Elements/ShowTransaction:160 html/Ticket/Elements/Tabs:121 html/Work/Tickets/Display.html:31 html/Work/Tickets/Elements/ShowTransaction:108 +#: html/Ticket/Elements/ShowTransaction:172 html/Ticket/Elements/Tabs:121 html/Work/Tickets/Display.html:54 html/Work/Tickets/Elements/ShowTransaction:115 msgid "Reply" msgstr "回覆" @@ -4651,15 +4855,15 @@ msgstr "å°ç”³è«‹å–®é€²è¡Œå›žè¦†" msgid "ReplyToTicket" msgstr "回覆申請單" -#: html/Edit/Users/Info:45 +#: NOT FOUND IN SOURCE msgid "Report to Duty" msgstr "上下ç刷å¡" -#: html/Edit/Users/Info:33 +#: NOT FOUND IN SOURCE msgid "Reported on" msgstr "到è·æ—¥æœŸ" -#: etc/initialdata.zh:62 etc/initialdata:44 html/Ticket/Update.html:39 html/Work/Elements/List:21 html/Work/Elements/MyApprovals:12 html/Work/Elements/MyTickets:20 html/Work/Elements/SelectSearch:30 html/Work/Tickets/Elements/ShowBasics:62 lib/RT/ACE_Overlay.pm:86 +#: etc/initialdata:44 html/Ticket/Update.html:39 html/Work/Elements/List:21 html/Work/Elements/MyApprovals:12 html/Work/Elements/MyTickets:20 html/Work/Elements/SelectSearch:31 html/Work/Tickets/Elements/ShowBasics:62 lib/RT/ACE_Overlay.pm:86 msgid "Requestor" msgstr "申請人" @@ -4687,7 +4891,7 @@ msgstr "申請人" msgid "RequestorAddresses" msgstr "申請人地å€" -#: html/SelfService/Create.html:40 html/Ticket/Create.html:55 html/Ticket/Elements/EditPeople:47 html/Ticket/Elements/ShowPeople:30 +#: html/SelfService/Create.html:40 html/Ticket/Create.html:55 html/Ticket/Elements/EditPeople:47 html/Ticket/Elements/ShowPeople:30 html/Work/Tickets/Elements/EditPeople:38 msgid "Requestors" msgstr "申請人" @@ -4699,7 +4903,7 @@ msgstr "申請單處ç†æœŸé™" msgid "Reset" msgstr "é‡è¨" -#: html/Admin/Users/Modify.html:158 html/User/Prefs.html:49 html/Work/Preferences/Info:32 +#: html/Admin/Users/Modify.html:158 html/User/Prefs.html:63 html/Work/Preferences/Info:34 msgid "Residence" msgstr "ä½è™•" @@ -4707,16 +4911,16 @@ msgstr "ä½è™•" msgid "Resolution" msgstr "解決狀態" -#: html/Ticket/Elements/Tabs:131 html/Work/Tickets/Display.html:34 +#: html/Ticket/Elements/Tabs:131 html/Work/Tickets/Display.html:57 msgid "Resolve" msgstr "解決" -#: html/Ticket/Update.html:136 html/Work/Tickets/Update.html:120 +#: html/Ticket/Update.html:137 #. ($Ticket->id, $Ticket->Subject) msgid "Resolve ticket #%1 (%2)" msgstr "解決申請單 #%1 (%2)" -#: etc/initialdata.zh:331 etc/initialdata:308 html/Elements/SelectDateType:27 lib/RT/Ticket_Overlay.pm:1188 +#: etc/initialdata:308 html/Elements/SelectDateType:27 lib/RT/Ticket_Overlay.pm:1215 msgid "Resolved" msgstr "已解決" @@ -4724,7 +4928,7 @@ msgstr "已解決" msgid "Response to requestors" msgstr "回覆申請人" -#: html/Edit/Users/Info:44 +#: NOT FOUND IN SOURCE msgid "Responsibility Type" msgstr "責任å€åˆ†" @@ -4732,11 +4936,11 @@ msgstr "責任å€åˆ†" msgid "Results" msgstr "çµæžœ" -#: html/Search/Elements/PickRestriction:104 html/Work/Search/PickRestriction:84 +#: html/Search/Elements/PickRestriction:104 html/Work/Search/PickRestriction:90 msgid "Results per page" msgstr "æ¯é 列出幾ç†çµæžœ" -#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:99 html/User/Prefs.html:71 html/Work/Preferences/Info:54 +#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:99 html/User/Prefs.html:94 html/Work/Preferences/Info:56 msgid "Retype Password" msgstr "å†æ¬¡è¼¸å…¥å¯†ç¢¼" @@ -4776,17 +4980,17 @@ msgstr "權é™æ’¤æ¶ˆå®Œç•¢" msgid "Rights" msgstr "權é™åŠä»£ç†äºº" -#: lib/RT/Interface/Web.pm:794 x:797 +#: lib/RT/Interface/Web.pm:857 #. ($object_type) msgid "Rights could not be granted for %1" msgstr "無法將權é™è³¦äºˆ %1" -#: lib/RT/Interface/Web.pm:827 x:830 +#: lib/RT/Interface/Web.pm:887 #. ($object_type) msgid "Rights could not be revoked for %1" msgstr "無法撤消 %1 的權é™" -#: html/Edit/Groups/Member:55 html/Edit/Groups/Members/List:10 +#: html/Edit/Groups/Member:54 html/Edit/Groups/Members/List:10 msgid "Role Members" msgstr "角色æˆå“¡" @@ -4802,19 +5006,19 @@ msgstr "角色" msgid "RootApproval" msgstr "交由系統管ç†å“¡ç°½æ ¸" -#: html/Edit/Global/Workflow/Action:27 +#: html/Edit/Global/Workflow/Action:23 msgid "Run Approval" msgstr "ç°½æ ¸åŸ·è¡Œ" -#: html/Edit/Global/Basic/Top:72 +#: html/Edit/Global/Basic/Top:81 msgid "SMTPDebug" msgstr "SMTP åµéŒ¯ç´€éŒ„" -#: html/Edit/Global/Basic/Top:58 +#: html/Edit/Global/Basic/Top:63 msgid "SMTPFrom" msgstr "SMTP 寄件ä½å€" -#: html/Edit/Global/Basic/Top:56 +#: html/Edit/Global/Basic/Top:61 msgid "SMTPServer" msgstr "SMTP 伺æœå™¨" @@ -4826,7 +5030,7 @@ msgstr "星期å…" msgid "Sat." msgstr "星期å…" -#: html/Edit/Elements/104Buttons:72 html/Work/Preferences/index.html:35 +#: html/Edit/Elements/104Buttons:83 html/Work/Preferences/index.html:33 html/Work/Tickets/Elements/EditBasics:63 html/Work/Tickets/Elements/EditLinks:133 html/Work/Tickets/Elements/EditPeople:51 msgid "Save" msgstr "儲å˜" @@ -4852,7 +5056,7 @@ msgstr "訊æ¯é€šçŸ¥å‹•ä½œ" msgid "Scrip Condition" msgstr "訊æ¯é€šçŸ¥æ¢ä»¶" -#: lib/RT/Scrip_Overlay.pm:175 +#: lib/RT/Scrip_Overlay.pm:180 msgid "Scrip Created" msgstr "手續新增完畢" @@ -4860,7 +5064,7 @@ msgstr "手續新增完畢" msgid "Scrip Name" msgstr "訊æ¯å稱" -#: html/Admin/Elements/EditScrips:83 +#: html/Admin/Elements/EditScrips:85 msgid "Scrip deleted" msgstr "手續刪除完畢" @@ -4868,7 +5072,7 @@ msgstr "手續刪除完畢" msgid "Scrips" msgstr "手續" -#: html/Edit/Global/autohandler:9 html/Edit/Queues/autohandler:20 +#: html/Edit/Global/autohandler:9 html/Edit/Queues/autohandler:24 msgid "Scrips " msgstr "訊æ¯é€šçŸ¥" @@ -4880,7 +5084,7 @@ msgstr "%1 的手續\\n" msgid "Scrips which apply to all queues" msgstr "é©ç”¨æ–¼æ‰€æœ‰è¡¨å–®çš„手續" -#: html/Edit/Elements/104Buttons:75 html/Elements/SimpleSearch:26 html/Search/Elements/PickRestriction:125 html/Ticket/Elements/Tabs:158 html/Work/Elements/Tab:45 html/Work/Search/PickRestriction:102 +#: html/Edit/Elements/104Buttons:86 html/Elements/SimpleSearch:26 html/Search/Elements/PickRestriction:125 html/Ticket/Elements/Tabs:158 html/Work/Elements/Tab:45 html/Work/Search/PickRestriction:108 msgid "Search" msgstr "查詢" @@ -4896,7 +5100,7 @@ msgstr "ç°½æ ¸å–®æŸ¥è©¢" msgid "Second-" msgstr "二" -#: html/Edit/Users/Info:40 +#: NOT FOUND IN SOURCE msgid "Second-level Users" msgstr "二階主管員工" @@ -4976,7 +5180,7 @@ msgstr "多é‡é¸é …" msgid "SelectSingle" msgstr "單一é¸é …" -#: html/Edit/Elements/PickUsers:85 html/Edit/Users/Add.html:78 +#: html/Edit/Elements/PickUsers:87 html/Edit/Users/Add.html:78 msgid "Selected users:" msgstr "新增å°è±¡ï¼š" @@ -4984,39 +5188,39 @@ msgstr "新增å°è±¡ï¼š" msgid "Self Service" msgstr "自助æœå‹™" -#: etc/initialdata.zh:131 etc/initialdata:113 +#: etc/initialdata:113 msgid "Send mail to all watchers" msgstr "寄信給所有視察員" -#: etc/initialdata.zh:127 etc/initialdata:109 +#: etc/initialdata:109 msgid "Send mail to all watchers as a \"comment\"" msgstr "以評論方å¼å¯„信給所有視察員" -#: etc/initialdata.zh:122 etc/initialdata:104 +#: etc/initialdata:104 msgid "Send mail to requestors and Ccs" msgstr "寄信給申請人åŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:117 etc/initialdata:99 +#: etc/initialdata:99 msgid "Send mail to requestors and Ccs as a comment" msgstr "以評論方å¼å¯„信給申請人åŠå‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:96 etc/initialdata:78 +#: etc/initialdata:78 msgid "Sends a message to the requestors" msgstr "寄信給申請人" -#: etc/initialdata.zh:135 etc/initialdata.zh:139 etc/initialdata:117 etc/initialdata:121 +#: etc/initialdata:117 etc/initialdata:121 msgid "Sends mail to explicitly listed Ccs and Bccs" msgstr "寄信給特定的副本åŠå¯†ä»¶å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:112 etc/initialdata:94 +#: etc/initialdata:94 msgid "Sends mail to the administrative Ccs" msgstr "寄信給管ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:108 etc/initialdata:90 +#: etc/initialdata:90 msgid "Sends mail to the administrative Ccs as a comment" msgstr "以評論寄信給管ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:100 etc/initialdata.zh:104 etc/initialdata:82 etc/initialdata:86 +#: etc/initialdata:82 etc/initialdata:86 msgid "Sends mail to the owner" msgstr "寄信給申請人" @@ -5032,7 +5236,11 @@ msgstr "09" msgid "September" msgstr "ä¹æœˆ" -#: html/Edit/Users/Info:38 +#: NOT FOUND IN SOURCE +msgid "Setting %1's 'Disabled' property to %2" +msgstr "%1 的「åœç”¨ã€å±¬æ€§å·²è¨ç‚º %2" + +#: NOT FOUND IN SOURCE msgid "Shift Type" msgstr "ç別屬性" @@ -5100,7 +5308,7 @@ msgstr "登記æˆç‚ºç”³è«‹äººæˆ–副本收件人" msgid "Sign up as a ticket or queue AdminCc" msgstr "登記æˆç‚ºç®¡ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: html/Admin/Elements/ModifyUser:38 html/Admin/Users/Modify.html:190 html/Admin/Users/Prefs.html:31 html/User/Prefs.html:111 html/Work/Preferences/Info:111 +#: html/Admin/Elements/ModifyUser:38 html/Admin/Users/Modify.html:190 html/Admin/Users/Prefs.html:31 html/Edit/Users/Info:52 html/User/Prefs.html:148 html/Work/Preferences/Info:113 msgid "Signature" msgstr "ç°½å檔" @@ -5124,7 +5332,7 @@ msgstr "é †åº" msgid "Sort key" msgstr "排åºæ–¹å¼" -#: html/Search/Elements/PickRestriction:108 html/Work/Search/PickRestriction:89 +#: html/Search/Elements/PickRestriction:108 html/Work/Search/PickRestriction:95 msgid "Sort results by" msgstr "çµæžœæŽ’åºæ–¹å¼" @@ -5132,7 +5340,7 @@ msgstr "çµæžœæŽ’åºæ–¹å¼" msgid "SortOrder" msgstr "排åºé †åº" -#: html/Work/Elements/List:8 html/Work/Elements/MyApprovals:11 +#: html/Admin/Elements/EditScrip:80 html/Edit/Global/Scrip/Top:75 html/Work/Elements/List:8 html/Work/Elements/MyApprovals:11 msgid "Stage" msgstr "é—œå¡" @@ -5152,7 +5360,7 @@ msgstr "延宕" msgid "Start page" msgstr "首é " -#: html/Elements/SelectDateType:26 html/Ticket/Elements/EditDates:31 html/Ticket/Elements/ShowDates:34 +#: html/Elements/SelectDateType:26 html/Ticket/Elements/EditDates:31 html/Ticket/Elements/ShowDates:35 html/Work/Tickets/Elements/EditBasics:35 msgid "Started" msgstr "實際起始日" @@ -5160,7 +5368,7 @@ msgstr "實際起始日" msgid "Started date '%1' could not be parsed" msgstr "無法解讀起始日期 '%1" -#: html/Elements/SelectDateType:30 html/Ticket/Create.html:165 html/Ticket/Elements/EditDates:26 html/Ticket/Elements/ShowDates:30 +#: html/Elements/SelectDateType:30 html/Ticket/Create.html:165 html/Ticket/Elements/EditDates:26 html/Ticket/Elements/ShowDates:31 html/Work/Tickets/Elements/EditBasics:26 msgid "Starts" msgstr "應起始日" @@ -5172,19 +5380,19 @@ msgstr "應起始日" msgid "Starts date '%1' could not be parsed" msgstr "無法解讀起始日期 '%1" -#: html/Admin/Elements/ModifyUser:81 html/Admin/Users/Modify.html:137 html/User/Prefs.html:93 html/Work/Preferences/Info:83 +#: html/Admin/Elements/ModifyUser:81 html/Admin/Users/Modify.html:137 html/User/Prefs.html:126 html/Work/Preferences/Info:85 msgid "State" msgstr "å·ž" -#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Search/Elements/PickRestriction:73 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:30 html/Ticket/Create.html:41 html/Ticket/Elements/EditBasics:37 html/Ticket/Elements/ShowBasics:30 html/Ticket/Update.html:59 html/Work/Elements/List:15 html/Work/Elements/MyRequests:18 html/Work/Elements/MyTickets:18 html/Work/Search/PickRestriction:54 html/Work/Tickets/Update.html:22 lib/RT/Ticket_Overlay.pm:1182 lib/RT/Tickets_Overlay.pm:908 +#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Search/Elements/PickRestriction:73 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:30 html/Ticket/Create.html:41 html/Ticket/Elements/EditBasics:37 html/Ticket/Elements/ShowBasics:30 html/Ticket/Update.html:59 html/Work/Elements/List:15 html/Work/Elements/MyRequests:18 html/Work/Elements/MyTickets:18 html/Work/Search/PickRestriction:54 html/Work/Tickets/Elements/EditBasics:19 html/Work/Tickets/Update.html:22 lib/RT/Ticket_Overlay.pm:1209 lib/RT/Tickets_Overlay.pm:927 msgid "Status" msgstr "ç¾æ³" -#: etc/initialdata.zh:317 etc/initialdata:294 +#: etc/initialdata:294 msgid "Status Change" msgstr "ç¾æ³æ”¹è®Šæ™‚" -#: lib/RT/Transaction_Overlay.pm:528 +#: lib/RT/Transaction_Overlay.pm:477 #. ($self->loc($self->OldValue), $self->loc($self->NewValue)) msgid "Status changed from %1 to %2" msgstr "ç¾æ³å¾ž %1 改為 %2" @@ -5205,25 +5413,25 @@ msgstr "強制承辦申請單" msgid "StealTicket" msgstr "強制承辦申請單" -#: lib/RT/Transaction_Overlay.pm:587 +#: lib/RT/Transaction_Overlay.pm:545 #. ($Old->Name) msgid "Stolen from %1 " -msgstr "被 %1 å¼·åˆ¶æ›´æ› " +msgstr "承辦人從 %1 強制更æ›" -#: html/Edit/Groups/Member:69 +#: html/Edit/Groups/Member:68 msgid "Subgroup" msgstr "å群組" -#: html/Elements/MyRequests:28 html/Elements/MyTickets:28 html/Search/Bulk.html:135 html/Search/Elements/PickRestriction:42 html/SelfService/Create.html:56 html/SelfService/Elements/MyRequests:27 html/SelfService/Update.html:31 html/Ticket/Create.html:83 html/Ticket/Elements/EditBasics:27 html/Ticket/ModifyAll.html:78 html/Ticket/Update.html:75 html/Work/Elements/MyApprovals:9 html/Work/Elements/MyRequests:16 html/Work/Elements/MyTickets:16 html/Work/Search/Bulk.html:87 html/Work/Search/PickRestriction:22 html/Work/Tickets/Create.html:131 html/Work/Tickets/Elements/ShowBasics:36 lib/RT/Ticket_Overlay.pm:1178 lib/RT/Tickets_Overlay.pm:987 +#: html/Elements/MyRequests:28 html/Elements/MyTickets:28 html/Search/Bulk.html:135 html/Search/Elements/PickRestriction:42 html/SelfService/Create.html:56 html/SelfService/Elements/MyRequests:27 html/SelfService/Update.html:31 html/Ticket/Create.html:83 html/Ticket/Elements/EditBasics:27 html/Ticket/ModifyAll.html:78 html/Ticket/Update.html:75 html/Work/Elements/MyApprovals:9 html/Work/Elements/MyRequests:16 html/Work/Elements/MyTickets:16 html/Work/Search/Bulk.html:87 html/Work/Search/PickRestriction:22 html/Work/Tickets/Elements/AddSubject:8 html/Work/Tickets/Elements/EditBasics:8 html/Work/Tickets/Elements/ShowBasics:36 html/Work/Tickets/Elements/ShowSubject:8 lib/RT/Ticket_Overlay.pm:1205 lib/RT/Tickets_Overlay.pm:1006 msgid "Subject" msgstr "主題" -#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:609 +#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/StyleGuide.pod:795 lib/RT/Transaction_Overlay.pm:567 #. ($self->Data) msgid "Subject changed to %1" msgstr "標題已改為 %1" -#: html/Elements/Submit:58 html/Work/Search/Bulk.html:103 +#: html/Edit/Users/Info:71 html/Elements/Submit:58 html/Work/Search/Bulk.html:103 msgid "Submit" msgstr "é€å‡º" @@ -5231,7 +5439,7 @@ msgstr "é€å‡º" msgid "Submit Workflow" msgstr "é€å‡ºæµç¨‹" -#: lib/RT/Group_Overlay.pm:748 +#: lib/RT/Group_Overlay.pm:746 msgid "Succeeded" msgstr "è¨å®šæˆåŠŸ" @@ -5247,6 +5455,18 @@ msgstr "星期日" msgid "SuperUser" msgstr "系統管ç†å“¡" +#: html/Edit/Global/Basic/Top:29 +msgid "Sync now" +msgstr "執行åŒæ¥" + +#: html/Edit/Global/Basic/Top:87 +msgid "Sync104HRMS" +msgstr "自動åŒæ¥104HRMS" + +#: NOT FOUND IN SOURCE +msgid "Synchronizing HRMS data. This may take a while..." +msgstr "æ£åœ¨åŒæ¥åŒ– HRMS 人事系統資料。請ç¨å¾…..." + #: html/User/Elements/DelegateRights:76 msgid "System" msgstr "系統" @@ -5255,7 +5475,7 @@ msgstr "系統" msgid "System Defined" msgstr "系統定義" -#: html/Admin/Elements/SelectRights:80 lib/RT/ACE_Overlay.pm:566 lib/RT/Interface/Web.pm:793 lib/RT/Interface/Web.pm:826 x:796 x:829 +#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:566 lib/RT/Interface/Web.pm:856 lib/RT/Interface/Web.pm:886 msgid "System Error" msgstr "系統錯誤" @@ -5267,7 +5487,7 @@ msgstr "系統錯誤。è¨å®šæ¬Šé™å¤±æ•—。" msgid "System Error. right not granted" msgstr "系統錯誤。è¨å®šæ¬Šé™å¤±æ•—。" -#: html/Edit/Users/index.html:122 +#: html/Edit/Users/index.html:95 msgid "System Rights" msgstr "系統權é™" @@ -5291,11 +5511,11 @@ msgstr "系統群組" msgid "SystemInternal" msgstr "系統內部用" -#: etc/initialdata.zh:59 etc/initialdata.zh:65 etc/initialdata.zh:71 etc/initialdata:41 etc/initialdata:47 etc/initialdata:53 +#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53 msgid "SystemRolegroup for internal use" msgstr "內部使用的系統角色群組" -#: lib/RT/CurrentUser.pm:319 +#: lib/RT/CurrentUser.pm:318 msgid "TEST_STRING" msgstr "TEST_STRING" @@ -5315,11 +5535,11 @@ msgstr "自行承辦申請單" msgid "TakeTicket" msgstr "自行承辦申請單" -#: lib/RT/Transaction_Overlay.pm:573 +#: lib/RT/Transaction_Overlay.pm:530 msgid "Taken" msgstr "å·²å—ç†" -#: html/Admin/Elements/EditScrip:80 +#: html/Admin/Elements/EditScrip:88 msgid "Template" msgstr "範本" @@ -5344,7 +5564,7 @@ msgstr "通知範本å稱" msgid "Template deleted" msgstr "範本已刪除" -#: lib/RT/Scrip_Overlay.pm:152 +#: lib/RT/Scrip_Overlay.pm:156 msgid "Template not found" msgstr "找ä¸åˆ°ç¯„本" @@ -5352,7 +5572,7 @@ msgstr "找ä¸åˆ°ç¯„本" msgid "Template not found\\n" msgstr "找ä¸åˆ°ç¯„本\\n" -#: lib/RT/Template_Overlay.pm:352 +#: lib/RT/Template_Overlay.pm:359 msgid "Template parsed" msgstr "範本剖æžå®Œç•¢" @@ -5360,7 +5580,7 @@ msgstr "範本剖æžå®Œç•¢" msgid "Templates" msgstr "範本" -#: html/Edit/Global/autohandler:8 html/Edit/Queues/autohandler:19 +#: html/Edit/Global/autohandler:8 html/Edit/Queues/autohandler:23 msgid "Templates " msgstr "通知範本" @@ -5368,7 +5588,7 @@ msgstr "通知範本" msgid "Templates for %1\\n" msgstr "找ä¸åˆ° %1 的範本\\n" -#: lib/RT/Interface/Web.pm:894 x:897 +#: lib/RT/Interface/Web.pm:954 msgid "That is already the current value" msgstr "已經是目å‰æ¬„ä½çš„值" @@ -5376,7 +5596,7 @@ msgstr "已經是目å‰æ¬„ä½çš„值" msgid "That is not a value for this custom field" msgstr "這ä¸æ˜¯è©²è‡ªè¨‚欄ä½çš„值" -#: lib/RT/Ticket_Overlay.pm:1899 +#: lib/RT/Ticket_Overlay.pm:1926 msgid "That is the same value" msgstr "åŒæ¨£çš„值" @@ -5389,7 +5609,7 @@ msgstr "é€™é …å–®ä½å·²ç¶“æ“有該權é™" msgid "That principal is already a %1 for this queue" msgstr "é€™é …å–®ä½å·²ç¶“是這個表單的 %1" -#: lib/RT/Ticket_Overlay.pm:1433 +#: lib/RT/Ticket_Overlay.pm:1460 #. ($self->loc($args{'Type'})) msgid "That principal is already a %1 for this ticket" msgstr "é€™é …å–®ä½å·²ç¶“是這份申請單的 %1" @@ -5399,16 +5619,16 @@ msgstr "é€™é …å–®ä½å·²ç¶“是這份申請單的 %1" msgid "That principal is not a %1 for this queue" msgstr "é€™é …å–®ä½ä¸æ˜¯é€™å€‹è¡¨å–®çš„ %1" -#: lib/RT/Ticket_Overlay.pm:1550 +#: lib/RT/Ticket_Overlay.pm:1577 #. ($args{'Type'}) msgid "That principal is not a %1 for this ticket" msgstr "é€™é …å–®ä½ä¸æ˜¯é€™ä»½ç”³è«‹å–®çš„ %1" -#: lib/RT/Ticket_Overlay.pm:1895 +#: lib/RT/Ticket_Overlay.pm:1922 msgid "That queue does not exist" msgstr "æ¤è¡¨å–®ä¸å˜åœ¨" -#: lib/RT/Ticket_Overlay.pm:3237 +#: lib/RT/Ticket_Overlay.pm:3293 msgid "That ticket has unresolved dependencies" msgstr "這份申請單有尚未解決的附屬申請單" @@ -5416,27 +5636,27 @@ msgstr "這份申請單有尚未解決的附屬申請單" msgid "That user already has that right" msgstr "ä½¿ç”¨è€…å·²å…·æœ‰è©²é …æ¬Šé™" -#: lib/RT/Ticket_Overlay.pm:3047 +#: lib/RT/Ticket_Overlay.pm:3097 msgid "That user already owns that ticket" msgstr "該使用者已經承辦這份申請單" -#: lib/RT/Ticket_Overlay.pm:3019 +#: lib/RT/Ticket_Overlay.pm:3069 msgid "That user does not exist" msgstr "使用者ä¸å˜åœ¨" -#: lib/RT/User_Overlay.pm:376 +#: lib/RT/User_Overlay.pm:381 msgid "That user is already privileged" msgstr "這å使用者已經是內部æˆå“¡" -#: lib/RT/User_Overlay.pm:397 +#: lib/RT/User_Overlay.pm:402 msgid "That user is already unprivileged" msgstr "這å使用者屬於éžå…§éƒ¨æˆå“¡ç¾¤çµ„" -#: lib/RT/User_Overlay.pm:389 +#: lib/RT/User_Overlay.pm:394 msgid "That user is now privileged" msgstr "ä½¿ç”¨è€…åŠ å…¥å…§éƒ¨æˆå“¡ç¾¤çµ„完畢" -#: lib/RT/User_Overlay.pm:410 +#: lib/RT/User_Overlay.pm:415 msgid "That user is now unprivileged" msgstr "這åä½¿ç”¨è€…å·²åŠ å…¥éžå…§éƒ¨æˆå“¡ç¾¤çµ„" @@ -5444,7 +5664,7 @@ msgstr "這åä½¿ç”¨è€…å·²åŠ å…¥éžå…§éƒ¨æˆå“¡ç¾¤çµ„" msgid "That user is now unprivilegedileged" msgstr "這åä½¿ç”¨è€…å·²åŠ å…¥éžå…§éƒ¨æˆå“¡ç¾¤çµ„" -#: lib/RT/Ticket_Overlay.pm:3040 +#: lib/RT/Ticket_Overlay.pm:3090 msgid "That user may not own tickets in that queue" msgstr "使用者å¯èƒ½æ²’有承辦表單裡的申請單" @@ -5464,7 +5684,7 @@ msgstr "申請單的副本收件人" msgid "The administrative CC of a ticket" msgstr "申請單的管ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: lib/RT/Ticket_Overlay.pm:2226 +#: lib/RT/Ticket_Overlay.pm:2255 msgid "The comment has been recorded" msgstr "評論已被紀錄" @@ -5476,7 +5696,7 @@ msgstr "下列命令會找到 'general' 表單內所有é‹ä½œä¸çš„申請單,ä msgid "The following commands were not proccessed:\\n\\n" msgstr "以下命令未被執行:\\n\\n" -#: lib/RT/Interface/Web.pm:897 x:900 +#: lib/RT/Interface/Web.pm:957 msgid "The new value has been set." msgstr "新的欄ä½å€¼è¨å®šå®Œæˆã€‚" @@ -5504,7 +5724,7 @@ msgstr "申請單 %1 %2 (%3)\\n" msgid "This tool allows the user to run arbitrary perl modules from within RT." msgstr "æ¤å·¥å…·ç¨‹å¼æœƒè®“使用者經由 RT 執行任æ„命令。" -#: lib/RT/Transaction_Overlay.pm:251 +#: lib/RT/Transaction_Overlay.pm:200 msgid "This transaction appears to have no content" msgstr "æ¤é …æ›´å‹•å ±å‘Šæ²’æœ‰å…§å®¹" @@ -5525,7 +5745,7 @@ msgstr "星期四" msgid "Thu." msgstr "星期四" -#: html/Admin/Elements/ModifyTemplateAsWorkflow:163 +#: html/Admin/Elements/ModifyTemplateAsWorkflow:163 html/Edit/Global/Workflow/Condition:24 msgid "Ticket" msgstr "申請單" @@ -5547,7 +5767,7 @@ msgstr "更新申請單 #%1 的全部資訊:%2" msgid "Ticket #%1: %2" msgstr "申請單 #%1: %2" -#: lib/RT/Ticket_Overlay.pm:605 lib/RT/Ticket_Overlay.pm:626 +#: lib/RT/Ticket_Overlay.pm:632 lib/RT/Ticket_Overlay.pm:653 #. ($self->Id, $QueueObj->Name) msgid "Ticket %1 created in queue '%2'" msgstr "申請單 #%1 æˆåŠŸæ–°å¢žæ–¼ '%2' 表單" @@ -5557,12 +5777,12 @@ msgstr "申請單 #%1 æˆåŠŸæ–°å¢žæ–¼ '%2' 表單" msgid "Ticket %1 loaded\\n" msgstr "載入申請單 %1\\n" -#: html/Search/Bulk.html:212 html/Work/Search/Bulk.html:169 +#: html/Search/Bulk.html:213 html/Work/Search/Bulk.html:169 #. ($Ticket->Id,$_) msgid "Ticket %1: %2" msgstr "申請單 %1:%2" -#: html/Edit/Queues/Basic/Top:28 html/Edit/Queues/List:16 html/Work/Queues/List:9 +#: html/Edit/Queues/Basic/Top:30 html/Edit/Queues/List:30 html/Work/Queues/List:9 msgid "Ticket Due" msgstr "表單處ç†æœŸé™" @@ -5583,11 +5803,11 @@ msgstr "申請單編號" msgid "Ticket Processing Due" msgstr "表單é‹è¡ŒæœŸé™" -#: etc/initialdata.zh:332 etc/initialdata:309 +#: etc/initialdata:309 msgid "Ticket Resolved" msgstr "申請單已解決" -#: html/Edit/Queues/Basic/Top:18 html/Edit/Queues/Category/List:6 html/Edit/Queues/Category/Top:7 html/Edit/Queues/List:7 html/Edit/Queues/index.html:31 html/Work/Delegates/List:7 html/Work/Delegates/index.html:11 html/Work/Elements/List:12 html/Work/Elements/SelectSearch:9 html/Work/Queues/List:6 html/Work/Queues/Select.html:12 html/Work/Queues/index.html:11 html/Work/Tickets/Create.html:44 html/Work/Tickets/Elements/ShowBasics:34 +#: html/Edit/Queues/Basic/Top:20 html/Edit/Queues/Category/List:6 html/Edit/Queues/Category/Top:7 html/Edit/Queues/List:21 html/Work/Delegates/List:7 html/Work/Delegates/index.html:11 html/Work/Elements/List:12 html/Work/Elements/SelectSearch:9 html/Work/Queues/List:6 html/Work/Queues/Select.html:12 html/Work/Queues/index.html:11 html/Work/Tickets/Create.html:43 html/Work/Tickets/Elements/ShowBasics:34 msgid "Ticket Type" msgstr "表單種類" @@ -5595,19 +5815,19 @@ msgstr "表單種類" msgid "Ticket attachment" msgstr "申請單附件" -#: lib/RT/Tickets_Overlay.pm:1166 +#: lib/RT/Tickets_Overlay.pm:1185 msgid "Ticket content" msgstr "申請單內容" -#: lib/RT/Tickets_Overlay.pm:1212 +#: lib/RT/Tickets_Overlay.pm:1231 msgid "Ticket content type" msgstr "申請單內容類別" -#: lib/RT/Ticket_Overlay.pm:496 lib/RT/Ticket_Overlay.pm:505 lib/RT/Ticket_Overlay.pm:515 lib/RT/Ticket_Overlay.pm:615 +#: lib/RT/Ticket_Overlay.pm:520 lib/RT/Ticket_Overlay.pm:529 lib/RT/Ticket_Overlay.pm:539 lib/RT/Ticket_Overlay.pm:642 msgid "Ticket could not be created due to an internal error" msgstr "內部錯誤,無法新增申請單" -#: lib/RT/Transaction_Overlay.pm:520 +#: lib/RT/Transaction_Overlay.pm:469 msgid "Ticket created" msgstr "申請單新增完畢" @@ -5615,7 +5835,7 @@ msgstr "申請單新增完畢" msgid "Ticket creation failed" msgstr "申請單新增失敗" -#: lib/RT/Transaction_Overlay.pm:525 +#: lib/RT/Transaction_Overlay.pm:474 msgid "Ticket deleted" msgstr "申請單刪除完畢" @@ -5631,7 +5851,7 @@ msgstr "申請單刪除完畢" msgid "Ticket not found" msgstr "找ä¸åˆ°ç”³è«‹å–®" -#: etc/initialdata.zh:318 etc/initialdata:295 +#: etc/initialdata:295 msgid "Ticket status changed" msgstr "申請單ç¾æ³å·²æ”¹è®Š" @@ -5643,12 +5863,12 @@ msgstr "申請單視察員" msgid "Tickets" msgstr "申請單" -#: lib/RT/Tickets_Overlay.pm:1383 +#: lib/RT/Tickets_Overlay.pm:1402 #. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'})) msgid "Tickets %1 %2" msgstr "申請單 %1 %2" -#: lib/RT/Tickets_Overlay.pm:1348 +#: lib/RT/Tickets_Overlay.pm:1367 #. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'})) msgid "Tickets %1 by %2" msgstr "申請單 %1 (%2)" @@ -5670,15 +5890,15 @@ msgstr "%1 的申請單" msgid "Tickets which depend on this approval:" msgstr "批准之後,å¯æŽ¥çºŒè™•ç†ï¼š" -#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:47 +#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:47 html/Work/Tickets/Elements/EditBasics:32 msgid "Time Left" msgstr "剩餘時間" -#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:42 +#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:42 html/Work/Tickets/Elements/EditBasics:24 msgid "Time Worked" msgstr "處ç†æ™‚é–“" -#: lib/RT/Tickets_Overlay.pm:1139 +#: lib/RT/Tickets_Overlay.pm:1158 msgid "Time left" msgstr "剩餘時間" @@ -5686,7 +5906,7 @@ msgstr "剩餘時間" msgid "Time to display" msgstr "顯示時間" -#: lib/RT/Tickets_Overlay.pm:1115 +#: lib/RT/Tickets_Overlay.pm:1134 msgid "Time worked" msgstr "已處ç†æ™‚é–“" @@ -5694,7 +5914,7 @@ msgstr "已處ç†æ™‚é–“" msgid "TimeLeft" msgstr "剩餘時間" -#: lib/RT/Ticket_Overlay.pm:1183 +#: lib/RT/Ticket_Overlay.pm:1210 msgid "TimeWorked" msgstr "已處ç†æ™‚é–“" @@ -5706,32 +5926,40 @@ msgstr "產生這次更動的差異檔:" msgid "To generate a diff of this commit:\\n" msgstr "產生這次更動的差異檔:\\n" -#: lib/RT/Ticket_Overlay.pm:1186 +#: lib/RT/Ticket_Overlay.pm:1213 msgid "Told" msgstr "告知日期" -#: html/Edit/Elements/Page:46 +#: html/Edit/Elements/Page:47 msgid "Total" msgstr "é " -#: etc/initialdata.zh:239 etc/initialdata:237 +#: etc/initialdata:237 msgid "Transaction" msgstr "æ›´å‹•" -#: lib/RT/Transaction_Overlay.pm:640 +#: lib/RT/Transaction_Overlay.pm:666 #. ($self->Data) msgid "Transaction %1 purged" msgstr "æ¸…é™¤æ›´å‹•å ±å‘Š %1" -#: lib/RT/Transaction_Overlay.pm:177 +#: lib/RT/Transaction_Overlay.pm:126 msgid "Transaction Created" msgstr "æ›´å‹•å ±å‘Šå·²æ–°å¢ž" -#: lib/RT/Transaction_Overlay.pm:88 +#: lib/RT/Transaction_Overlay.pm:90 msgid "Transaction->Create couldn't, as you didn't specify a ticket id" msgstr "未指定申請單編號,無法新增更動" -#: lib/RT/Transaction_Overlay.pm:699 +#: NOT FOUND IN SOURCE +msgid "TransactionBatch" +msgstr "批次更動時" + +#: NOT FOUND IN SOURCE +msgid "TransactionCreate" +msgstr "新增更動時" + +#: lib/RT/Transaction_Overlay.pm:721 msgid "Transactions are immutable" msgstr "ä¸å¯æ›´æ”¹æ›´å‹•å ±å‘Š" @@ -5747,7 +5975,7 @@ msgstr "星期二" msgid "Tue." msgstr "星期二" -#: html/Admin/Elements/EditCustomField:43 html/Admin/Elements/ModifyTemplateAsWorkflow:135 html/Ticket/Elements/AddWatchers:32 html/Ticket/Elements/AddWatchers:43 html/Ticket/Elements/AddWatchers:53 lib/RT/Ticket_Overlay.pm:1184 lib/RT/Tickets_Overlay.pm:959 +#: html/Admin/Elements/EditCustomField:43 html/Admin/Elements/ModifyTemplateAsWorkflow:135 html/Ticket/Elements/AddWatchers:32 html/Ticket/Elements/AddWatchers:43 html/Ticket/Elements/AddWatchers:53 lib/RT/Ticket_Overlay.pm:1211 lib/RT/Tickets_Overlay.pm:978 msgid "Type" msgstr "類別" @@ -5763,7 +5991,7 @@ msgstr "外部系統登入帳號" msgid "UnixUsername" msgstr "外部系統登入帳號" -#: lib/RT/Attachment_Overlay.pm:266 lib/RT/Attachment_Overlay.pm:298 +#: lib/RT/Attachment_Overlay.pm:281 lib/RT/Attachment_Overlay.pm:313 #. ($self->ContentEncoding) msgid "Unknown ContentEncoding %1" msgstr "ä¸å¯è§£çš„內容文å—ç·¨ç¢¼æ–¹å¼ %1" @@ -5772,11 +6000,11 @@ msgstr "ä¸å¯è§£çš„內容文å—ç·¨ç¢¼æ–¹å¼ %1" msgid "Unlimited" msgstr "全數顯示" -#: etc/initialdata.zh:50 etc/initialdata:32 +#: etc/initialdata:32 msgid "Unprivileged" msgstr "éžå…§éƒ¨æˆå“¡" -#: lib/RT/Transaction_Overlay.pm:569 +#: lib/RT/Transaction_Overlay.pm:526 msgid "Untaken" msgstr "未被å—ç†" @@ -5784,7 +6012,7 @@ msgstr "未被å—ç†" msgid "Up" msgstr "上一é " -#: html/Elements/MyTickets:63 html/Search/Bulk.html:32 html/Work/Elements/MyTickets:82 html/Work/Search/Bulk.html:10 html/Work/Tickets/Elements/EditCustomFieldEntries:97 +#: html/Elements/MyTickets:63 html/Search/Bulk.html:32 html/Work/Elements/MyTickets:83 html/Work/Search/Bulk.html:10 html/Work/Tickets/Elements/EditCustomFieldEntries:63 msgid "Update" msgstr "處ç†" @@ -5808,7 +6036,7 @@ msgstr "æ›´æ–°é›»å郵件信箱" msgid "Update name" msgstr "更新帳號" -#: lib/RT/Interface/Web.pm:409 x:412 +#: lib/RT/Interface/Web.pm:467 msgid "Update not recorded." msgstr "更新未被記錄" @@ -5828,21 +6056,21 @@ msgstr "更新申請單" msgid "Update ticket # %1" msgstr "更新申請單 # %1" -#: html/SelfService/Update.html:24 html/SelfService/Update.html:46 +#: html/SelfService/Update.html:24 html/SelfService/Update.html:63 #. ($Ticket->id) msgid "Update ticket #%1" msgstr "更新申請單 #%1" -#: html/Ticket/Update.html:138 html/Work/Tickets/Update.html:122 +#: html/Ticket/Update.html:139 #. ($Ticket->id, $Ticket->Subject) msgid "Update ticket #%1 (%2)" msgstr "更新申請單 #%1 (%2)" -#: lib/RT/Interface/Web.pm:407 x:410 +#: lib/RT/Interface/Web.pm:465 msgid "Update type was neither correspondence nor comment." msgstr "更新的內容並éžç”³è«‹å–®å›žè¦†ä¹Ÿä¸æ˜¯è©•è«–" -#: html/Elements/SelectDateType:32 html/Ticket/Elements/ShowDates:50 lib/RT/Ticket_Overlay.pm:1187 +#: html/Elements/SelectDateType:32 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1214 msgid "Updated" msgstr "å‰æ¬¡æ›´æ–°" @@ -5866,23 +6094,23 @@ msgstr "找ä¸åˆ°ä½¿ç”¨è€… '%1'" msgid "User '%1' not found\\n" msgstr "找ä¸åˆ°ä½¿ç”¨è€… '%1'\\n" -#: etc/initialdata.zh:142 etc/initialdata.zh:209 etc/initialdata:124 etc/initialdata:191 +#: etc/initialdata:124 etc/initialdata:191 msgid "User Defined" msgstr "使用者自訂" -#: html/Admin/Users/Prefs.html:58 html/Edit/Users/List:13 html/Edit/Users/Top:42 +#: html/Admin/Users/Prefs.html:58 msgid "User ID" msgstr "使用者 ID" -#: html/Elements/SelectUsers:25 +#: html/Edit/Elements/SelectUsers:3 html/Elements/SelectUsers:25 msgid "User Id" msgstr "使用者 ID" -#: html/Edit/Elements/PickUsers:12 html/Edit/Global/UserRight/List:7 html/Edit/Global/UserRight/Top:9 html/Edit/Users/Add.html:13 html/Edit/Users/List:5 html/Edit/Users/Search.html:23 html/Edit/Users/Top:8 html/Work/Delegates/Info:60 html/Work/Tickets/Cc:10 +#: html/Edit/Elements/PickUsers:12 html/Edit/Global/UserRight/List:7 html/Edit/Global/UserRight/Top:9 html/Edit/Users/Add.html:13 html/Edit/Users/Search.html:23 html/Work/Delegates/Info:60 html/Work/Tickets/Cc:10 msgid "User Number" msgstr "員工編號" -#: html/Admin/Elements/GroupTabs:46 html/Admin/Elements/QueueTabs:59 html/Admin/Elements/SystemTabs:46 html/Admin/Global/index.html:58 html/Edit/Global/autohandler:11 html/Edit/Queues/autohandler:22 +#: html/Admin/Elements/GroupTabs:46 html/Admin/Elements/QueueTabs:59 html/Admin/Elements/SystemTabs:46 html/Admin/Global/index.html:58 html/Edit/Global/autohandler:11 html/Edit/Queues/autohandler:26 msgid "User Rights" msgstr "使用者權é™" @@ -5890,7 +6118,7 @@ msgstr "使用者權é™" msgid "User Setup" msgstr "使用者è¨å®š" -#: html/Edit/Users/Info:37 +#: NOT FOUND IN SOURCE msgid "User Shift" msgstr "å“¡å·¥ç別" @@ -5899,15 +6127,23 @@ msgstr "å“¡å·¥ç別" msgid "User could not be created: %1" msgstr "無法新增使用者:%1" -#: lib/RT/User_Overlay.pm:321 +#: lib/RT/User_Overlay.pm:326 msgid "User created" msgstr "使用者新增完畢" +#: NOT FOUND IN SOURCE +msgid "User created: %1" +msgstr "使用者 %1 新增完畢" + +#: NOT FOUND IN SOURCE +msgid "User created: %1 (%2)" +msgstr "使用者 %1 (%2) 新增完畢" + #: html/Admin/Global/GroupRights.html:66 html/Admin/Groups/GroupRights.html:53 html/Admin/Queues/GroupRights.html:68 msgid "User defined groups" msgstr "使用者定義的群組" -#: lib/RT/User_Overlay.pm:575 lib/RT/User_Overlay.pm:592 +#: lib/RT/User_Overlay.pm:580 lib/RT/User_Overlay.pm:597 msgid "User loaded" msgstr "已載入使用者" @@ -5915,6 +6151,10 @@ msgstr "已載入使用者" msgid "User notified" msgstr "已通知使用者" +#: NOT FOUND IN SOURCE +msgid "User renamed from %1 to %2" +msgstr "使用者 %1 已改å為 %2" + #: html/Admin/Users/Prefs.html:24 html/Admin/Users/Prefs.html:28 msgid "User view" msgstr "使用者ç§äººè³‡æ–™" @@ -5927,7 +6167,7 @@ msgstr "使用者自定" msgid "Username" msgstr "帳號" -#: html/Admin/Elements/SelectNewGroupMembers:25 html/Admin/Elements/Tabs:31 html/Admin/Groups/Members.html:54 html/Admin/Queues/People.html:67 html/Admin/index.html:28 html/User/Groups/Members.html:57 html/Work/Tickets/Elements/ShowTransaction:8 +#: html/Admin/Elements/SelectNewGroupMembers:25 html/Admin/Elements/Tabs:31 html/Admin/Groups/Members.html:54 html/Admin/Queues/People.html:67 html/Admin/index.html:28 html/Edit/Groups/Admin:9 html/User/Groups/Members.html:57 html/Work/Tickets/Elements/ShowTransaction:11 msgid "Users" msgstr "使用者" @@ -5935,7 +6175,7 @@ msgstr "使用者" msgid "Users matching search criteria" msgstr "符åˆæŸ¥è©¢æ¢ä»¶çš„使用者" -#: html/Search/Elements/PickRestriction:50 html/Work/Search/PickRestriction:31 +#: NOT FOUND IN SOURCE msgid "ValueOfQueue" msgstr "é¸æ“‡è¡¨å–®" @@ -5955,7 +6195,7 @@ msgstr "以管ç†å“¡å‰¯æœ¬æ”¶ä»¶äººèº«ä»½è¦–察" msgid "Watcher loaded" msgstr "æˆåŠŸè¼‰å…¥è¦–察員資訊" -#: html/Admin/Elements/QueueTabs:41 +#: html/Admin/Elements/QueueTabs:41 html/Edit/Elements/SelectQueues:5 msgid "Watchers" msgstr "視察員" @@ -5971,55 +6211,55 @@ msgstr "星期三" msgid "Wed." msgstr "星期三" -#: etc/initialdata.zh:533 etc/initialdata:503 etc/upgrade/2.1.71:161 html/Edit/Elements/CreateApprovalsQueue:135 +#: etc/initialdata:503 etc/upgrade/2.1.71:161 html/Edit/Elements/CreateApprovalsQueue:135 msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket" msgstr "當申請單通éŽæ‰€æœ‰ç°½æ ¸å¾Œï¼Œå°‡æ¤è¨Šæ¯å›žè¦†åˆ°åŽŸç”³è«‹å–®" -#: etc/initialdata.zh:497 etc/initialdata:467 etc/upgrade/2.1.71:135 html/Edit/Elements/CreateApprovalsQueue:107 +#: etc/initialdata:467 etc/upgrade/2.1.71:135 html/Edit/Elements/CreateApprovalsQueue:107 msgid "When a ticket has been approved by any approver, add correspondence to the original ticket" msgstr "當申請單通éŽæŸé …ç°½æ ¸å¾Œï¼Œå°‡æ¤è¨Šæ¯å›žè¦†åˆ°åŽŸç”³è«‹å–®" -#: etc/initialdata.zh:156 etc/initialdata:138 +#: etc/initialdata:138 msgid "When a ticket is created" msgstr "新增申請單時" -#: etc/initialdata.zh:428 etc/initialdata:400 etc/upgrade/2.1.71:79 html/Edit/Elements/CreateApprovalsQueue:51 +#: etc/initialdata:400 etc/upgrade/2.1.71:79 html/Edit/Elements/CreateApprovalsQueue:51 msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval" msgstr "ç°½æ ¸å–®æ–°å¢žä¹‹å¾Œï¼Œé€šçŸ¥æ‡‰å—ç†çš„承辦人åŠç®¡ç†å“¡å‰¯æœ¬æ”¶ä»¶äºº" -#: etc/initialdata.zh:161 etc/initialdata:143 +#: etc/initialdata:143 msgid "When anything happens" msgstr "當任何事情發生時" -#: etc/initialdata.zh:202 etc/initialdata:184 +#: etc/initialdata:184 msgid "Whenever a ticket is resolved" msgstr "當申請單解決時" -#: etc/initialdata.zh:188 etc/initialdata:170 +#: etc/initialdata:170 msgid "Whenever a ticket's owner changes" msgstr "當申請單更æ›æ‰¿è¾¦äººæ™‚" -#: etc/initialdata.zh:196 etc/initialdata:178 +#: etc/initialdata:178 msgid "Whenever a ticket's queue changes" msgstr "當申請單更æ›è¡¨å–®æ™‚" -#: etc/initialdata.zh:180 etc/initialdata:162 +#: etc/initialdata:162 msgid "Whenever a ticket's status changes" msgstr "當申請單更新ç¾æ³æ™‚" -#: etc/initialdata.zh:210 etc/initialdata:192 +#: etc/initialdata:192 msgid "Whenever a user-defined condition occurs" msgstr "當使用者自訂的情æ³ç™¼ç”Ÿæ™‚" -#: etc/initialdata.zh:174 etc/initialdata:156 +#: etc/initialdata:156 msgid "Whenever comments come in" msgstr "當評論é€é”時" -#: etc/initialdata.zh:167 etc/initialdata:149 +#: etc/initialdata:149 msgid "Whenever correspondence comes in" msgstr "當回覆é€é”時" -#: html/Admin/Users/Modify.html:163 html/User/Prefs.html:51 html/Work/Preferences/Info:34 +#: html/Admin/Users/Modify.html:163 html/User/Prefs.html:67 html/Work/Preferences/Info:36 msgid "Work" msgstr "å…¬å¸" @@ -6048,23 +6288,35 @@ msgstr "æµç¨‹çµæŸ" msgid "Workflow deleted" msgstr "æµç¨‹å·²åˆªé™¤" -#: html/Edit/Global/autohandler:10 html/Edit/Queues/autohandler:21 +#: html/Edit/Global/autohandler:10 html/Edit/Queues/autohandler:25 msgid "Workflows" msgstr "æµç¨‹" -#: html/Edit/Global/Basic/Top:25 +#: html/Edit/Global/CustomField/SelectWritable:5 +msgid "Writable" +msgstr "å¯è®€å¯«" + +#: html/autohandler:144 +msgid "XXX CHANGEME You are not an authorized user" +msgstr "XXX CHANGEME 您是未經授權的使用者" + +#: html/Edit/Global/Basic/Top:25 html/Edit/Queues/Basic/Top:82 msgid "Yes" msgstr "是" -#: lib/RT/Ticket_Overlay.pm:3150 +#: lib/RT/Ticket_Overlay.pm:3200 msgid "You already own this ticket" msgstr "您已是這份申請單的承辦人" -#: html/autohandler:122 +#: html/autohandler:136 msgid "You are not an authorized user" msgstr "您ä¸æ˜¯è¢«æŽˆæ¬Šçš„使用者" -#: lib/RT/Ticket_Overlay.pm:3032 +#: html/Ticket/Elements/ShowTransaction:81 +msgid "You can access it with the Download button on the right." +msgstr "您å¯ä»¥æŒ‰å³æ–¹çš„「下載ã€éµä¾†å–得。" + +#: lib/RT/Ticket_Overlay.pm:3082 msgid "You can only reassign tickets that you own or that are unowned" msgstr "祇能é‡æ–°æŒ‡æ´¾æ‚¨æ‰€æ‰¿è¾¦æˆ–是沒有承辦人的申請單" @@ -6072,7 +6324,7 @@ msgstr "祇能é‡æ–°æŒ‡æ´¾æ‚¨æ‰€æ‰¿è¾¦æˆ–是沒有承辦人的申請單" msgid "You don't have permission to view that ticket.\\n" msgstr "您沒有看那份申請單的權é™ã€‚\\n" -#: docs/design_docs/string-extraction-guide.txt:47 +#: docs/design_docs/string-extraction-guide.txt:47 lib/RT/StyleGuide.pod:760 #. ($num, $queue) msgid "You found %1 tickets in queue %2" msgstr "您會在表單 %2 找到 %1 的申請單" @@ -6085,11 +6337,11 @@ msgstr "您已登出 RT。" msgid "You have no permission to create tickets in that queue." msgstr "您沒有在該表單新增申請單的權é™ã€‚" -#: lib/RT/Ticket_Overlay.pm:1908 +#: lib/RT/Ticket_Overlay.pm:1935 msgid "You may not create requests in that queue." msgstr "您ä¸èƒ½åœ¨è©²è¡¨å–®ä¸æ出申請。" -#: html/Edit/Global/Basic/Top:38 +#: html/Edit/Global/Basic/Top:42 msgid "You need to restart the Request Tracker service for saved changes to take effect." msgstr "æ‚¨å¿…é ˆé‡æ–°å•Ÿå‹• Request Tracker æœå‹™ï¼Œå„²å˜çš„更動纔會生效。" @@ -6105,11 +6357,11 @@ msgstr "您æ出的 %1 申請單" msgid "Your RT administrator has misconfigured the mail aliases which invoke RT" msgstr "RT 管ç†å“¡å¯èƒ½è¨éŒ¯äº†ç”± RT 寄出的郵件收件人標é 檔" -#: etc/initialdata.zh:514 etc/initialdata:484 etc/upgrade/2.1.71:146 html/Edit/Elements/CreateApprovalsQueue:119 +#: etc/initialdata:484 etc/upgrade/2.1.71:146 html/Edit/Elements/CreateApprovalsQueue:119 msgid "Your request has been approved by %1. Other approvals may still be pending." msgstr "申請單已由 %1 批准。å¯èƒ½é‚„æœ‰å…¶ä»–å¾…ç°½æ ¸çš„æ¥é©Ÿã€‚" -#: etc/initialdata.zh:552 etc/initialdata:522 etc/upgrade/2.1.71:180 html/Edit/Elements/CreateApprovalsQueue:154 +#: etc/initialdata:522 etc/upgrade/2.1.71:180 html/Edit/Elements/CreateApprovalsQueue:154 msgid "Your request has been approved." msgstr "您的申請單已完æˆç°½æ ¸ç¨‹åºã€‚" @@ -6117,7 +6369,7 @@ msgstr "您的申請單已完æˆç°½æ ¸ç¨‹åºã€‚" msgid "Your request was rejected" msgstr "您的申請單已被é§å›ž" -#: etc/initialdata.zh:455 +#: NOT FOUND IN SOURCE msgid "Your request was rejected by %1." msgstr "您的申請單已被 %1 é§å›žã€‚" @@ -6125,11 +6377,11 @@ msgstr "您的申請單已被 %1 é§å›žã€‚" msgid "Your request was rejected." msgstr "您的申請單已被é§å›žã€‚" -#: html/autohandler:144 +#: html/autohandler:170 msgid "Your username or password is incorrect" msgstr "您的帳號或密碼有誤" -#: html/Admin/Elements/ModifyUser:83 html/Admin/Users/Modify.html:143 html/User/Prefs.html:95 html/Work/Preferences/Info:85 +#: html/Admin/Elements/ModifyUser:83 html/Admin/Users/Modify.html:143 html/User/Prefs.html:130 html/Work/Preferences/Info:87 msgid "Zip" msgstr "郵éžå€è™Ÿ" @@ -6145,6 +6397,10 @@ msgstr "éŽæœŸ" msgid "alert" msgstr "急訊" +#: NOT FOUND IN SOURCE +msgid "approving" +msgstr "å¾…ç°½æ ¸" + #: html/User/Elements/DelegateRights:58 #. ($right->PrincipalObj->Object->SelfDescription) msgid "as granted to %1" @@ -6166,11 +6422,11 @@ msgstr "內容" msgid "content-type" msgstr "é¡žåž‹" -#: lib/RT/Ticket_Overlay.pm:2295 +#: lib/RT/Ticket_Overlay.pm:2326 msgid "correspondence (probably) not sent" msgstr "申請單回覆(å¯èƒ½)未é€å‡º" -#: lib/RT/Ticket_Overlay.pm:2305 +#: lib/RT/Ticket_Overlay.pm:2336 msgid "correspondence sent" msgstr "申請單回覆已é€å‡º" @@ -6178,7 +6434,7 @@ msgstr "申請單回覆已é€å‡º" msgid "critical" msgstr "åš´é‡" -#: html/Admin/Elements/ModifyQueue:62 html/Admin/Queues/Modify.html:76 html/Edit/Queues/Basic/Top:31 html/Edit/Queues/List:18 html/Work/Queues/List:11 lib/RT/Date.pm:319 +#: html/Admin/Elements/ModifyQueue:62 html/Admin/Queues/Modify.html:76 html/Edit/Queues/Basic/Top:34 html/Edit/Queues/List:32 html/Work/Queues/List:11 lib/RT/Date.pm:319 msgid "days" msgstr "天" @@ -6247,11 +6503,11 @@ msgstr "編號" msgid "info" msgstr "資訊" -#: html/Elements/SelectBoolean:31 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:35 html/Search/Elements/PickRestriction:46 html/Search/Elements/PickRestriction:75 html/Search/Elements/PickRestriction:87 html/Work/Search/PickRestriction:27 html/Work/Search/PickRestriction:56 html/Work/Search/PickRestriction:69 +#: html/Elements/SelectBoolean:31 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:35 html/Search/Elements/PickRestriction:46 html/Search/Elements/PickRestriction:75 html/Search/Elements/PickRestriction:87 html/Work/Search/PickRestriction:27 html/Work/Search/PickRestriction:56 html/Work/Search/PickRestriction:75 msgid "is" msgstr "是" -#: html/Elements/SelectBoolean:35 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88 html/Work/Search/PickRestriction:28 html/Work/Search/PickRestriction:57 html/Work/Search/PickRestriction:70 +#: html/Elements/SelectBoolean:35 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88 html/Work/Search/PickRestriction:28 html/Work/Search/PickRestriction:57 html/Work/Search/PickRestriction:76 msgid "isn't" msgstr "ä¸æ˜¯" @@ -6287,11 +6543,15 @@ msgstr "月" msgid "new" msgstr "新建立" +#: html/Admin/Elements/EditCustomFields:42 +msgid "no name" +msgstr "沒有å稱" + #: html/Admin/Elements/EditScrips:42 msgid "no value" msgstr "沒有值" -#: html/Admin/Elements/EditQueueWatchers:26 html/Edit/Groups/Member:40 html/Edit/Groups/Members/Add.html:17 html/Edit/Groups/Members/List:8 html/Edit/Queues/Basic/Top:50 html/Edit/Queues/List:18 html/Ticket/Elements/EditWatchers:27 html/Work/Delegates/Info:37 html/Work/Delegates/Info:48 html/Work/Overview/Info:31 html/Work/Queues/List:11 html/Work/Tickets/Elements/ShowBasics:27 +#: html/Admin/Elements/EditQueueWatchers:26 html/Edit/Groups/Member:40 html/Edit/Groups/Members/Add.html:17 html/Edit/Groups/Members/List:8 html/Edit/Queues/List:32 html/Ticket/Elements/EditWatchers:27 html/Work/Delegates/Info:37 html/Work/Delegates/Info:48 html/Work/Overview/Info:31 html/Work/Queues/List:11 html/Work/Tickets/Elements/EditWatchers:5 html/Work/Tickets/Elements/ShowAttachments:30 html/Work/Tickets/Elements/ShowBasics:27 msgid "none" msgstr "ç„¡" @@ -6333,11 +6593,11 @@ msgstr "表單 %1 %2" msgid "rejected" msgstr "å·²é§å›ž" -#: html/Work/Elements/SelectSearch:21 lib/RT/Queue_Overlay.pm:60 +#: lib/RT/Queue_Overlay.pm:60 msgid "resolved" msgstr "已處ç†" -#: html/Edit/Global/Basic/Top:48 +#: html/Edit/Global/Basic/Top:53 msgid "rtname" msgstr "伺æœå™¨å稱" @@ -6363,16 +6623,21 @@ msgstr "系統群組 '%1'" msgid "the calling component did not specify why" msgstr "呼å«å…ƒä»¶æœªæŒ‡æ˜ŽåŽŸå› " +#: lib/RT/URI/fsck_com_rt.pm:234 +#. ($self->Object->Id) +msgid "ticket #%1" +msgstr "申請單 #%1" + #: lib/RT/Group_Overlay.pm:209 #. ($self->Instance, $self->Type) msgid "ticket #%1 %2" msgstr "申請單 #%1 %2" -#: html/Work/Elements/SelectSearch:27 +#: html/Work/Elements/SelectSearch:28 msgid "till" msgstr "至" -#: html/Edit/Elements/PickUsers:15 html/Edit/Global/Workflow/Condition:30 html/Edit/Users/Add.html:16 html/Edit/Users/Search.html:26 html/Work/Tickets/Cc:13 +#: html/Edit/Elements/PickUsers:15 html/Edit/Global/Workflow/Condition:31 html/Edit/Users/Add.html:16 html/Edit/Users/Search.html:26 html/Work/Tickets/Cc:13 msgid "to" msgstr "到" @@ -6385,7 +6650,7 @@ msgstr "真" msgid "undescribed group %1" msgstr "沒有æ述的群組 %1" -#: html/Work/Elements/SelectSearch:19 +#: NOT FOUND IN SOURCE msgid "unresolved" msgstr "未處ç†" @@ -6410,7 +6675,3 @@ msgstr "範本:%1" msgid "years" msgstr "å¹´" -#: lib/RT/Date.pm:331 -msgid "approving" -msgstr "å¾…ç°½æ ¸" - diff --git a/rt/lib/RT/Interface/Email.pm b/rt/lib/RT/Interface/Email.pm index bc1a55da2..241f5f35c 100755 --- a/rt/lib/RT/Interface/Email.pm +++ b/rt/lib/RT/Interface/Email.pm @@ -27,14 +27,14 @@ use strict; use Mail::Address; use MIME::Entity; use RT::EmailParser; - +use File::Temp; BEGIN { use Exporter (); use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); # set the version for version checking - $VERSION = do { my @r = (q$Revision: 1.1.1.1 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker + $VERSION = do { my @r = (q$Revision: 1.1.1.2 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker @ISA = qw(Exporter); @@ -153,6 +153,7 @@ sub MailError { Subject => 'There has been an error', Explanation => 'Unexplained error', MIMEObj => undef, + Attach => undef, LogLevel => 'crit', @_); @@ -175,7 +176,13 @@ sub MailError { $mimeobj->sync_headers(); $entity->add_part($mimeobj); } - + + if ($args{'Attach'}) { + $entity->attach(Data => $args{'Attach'}, Type => 'message/rfc822'); + + } + + if ($RT::MailCommand eq 'sendmailpipe') { open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0); print MAIL $entity->as_string; @@ -194,12 +201,6 @@ sub CreateUser { my ($Username, $Address, $Name, $ErrorsTo, $entity) = @_; my $NewUser = RT::User->new($RT::SystemUser); - # This data is tainted by some Very Broken mailers. - # (Sometimes they send raw ISO 8859-1 data here. fear that. - require Encode; - $Username = Encode::encode(utf8 => $Username, Encode::FB_PERLQQ()) if defined $Username; - $Name = Encode::encode(utf8 => $Name, Encode::FB_PERLQQ()) if defined $Name; - my ($Val, $Message) = $NewUser->Create(Name => ($Username || $Address), EmailAddress => $Address, @@ -361,36 +362,108 @@ sub ParseAddressFromHeader{ -=head2 Gateway +=head2 Gateway ARGSREF + + +Takes parameters: + + action + queue + message + This performs all the "guts" of the mail rt-mailgate program, and is designed to be called from the web interface with a message, user object, and so on. +Returns: + + An array of: + + (status code, message, optional ticket object) + + status code is a numeric value. + + for temporary failures, status code should be -75 + + for permanent failures which are handled by RT, status code should be 0 + + for succces, the status code should be 1 + + + =cut sub Gateway { - my %args = ( message => undef, - queue => 1, - action => 'correspond', - ticket => undef, - @_ ); + my $argsref = shift; + + my %args = %$argsref; + + # Set some reasonable defaults + $args{'action'} = 'correspond' unless ( $args{'action'} ); + $args{'queue'} = '1' unless ( $args{'queue'} ); # Validate the action unless ( $args{'action'} =~ /^(comment|correspond|action)$/ ) { # Can't safely loc this. What object do we loc around? - return ( 0, "Invalid 'action' parameter", undef ); + $RT::Logger->crit("Mail gateway called with an invalid action paramenter '".$args{'action'}."' for queue '".$args{'queue'}."'"); + + return ( -75, "Invalid 'action' parameter", undef ); } my $parser = RT::EmailParser->new(); - $parser->ParseMIMEEntityFromScalar( $args{'message'} ); + my ( $fh, $temp_file ); + for ( 1 .. 10 ) { + + # on NFS and NTFS, it is possible that tempfile() conflicts + # with other processes, causing a race condition. we try to + # accommodate this by pausing and retrying. + last if ( $fh, $temp_file ) = eval { File::Temp::tempfile(undef, UNLINK => 0) }; + sleep 1; + } + if ($fh) { + binmode $fh; #thank you, windows + $fh->autoflush(1); + print $fh $args{'message'}; + close($fh); + + if ( -f $temp_file ) { + $parser->ParseMIMEEntityFromFile($temp_file); + File::Temp::unlink0( $fh, $temp_file ); + if ($parser->Entity) { + delete $args{'message'}; + } + } + + } + + #If for some reason we weren't able to parse the message using a temp file + # try it with a scalar + if ($args{'message'}) { + $parser->ParseMIMEEntityFromScalar($args{'message'}); + + } + + if (!$parser->Entity()) { + MailError( + To => $RT::OwnerEmail, + Subject => "RT Bounce: Unparseable message", + Explanation => "RT couldn't process the message below", + Attach => $args{'message'} + ); + + return(0,"Failed to parse this message. Something is likely badly wrong with the message"); + } my $Message = $parser->Entity(); - my $head = $Message->head; + my $head = $Message->head; my ( $CurrentUser, $AuthStat, $status, $error ); + # Initalize AuthStat so comparisons work correctly + $AuthStat = -9999999; + my $ErrorsTo = ParseErrorsToAddressFromHead($head); my $MessageId = $head->get('Message-Id') @@ -400,37 +473,31 @@ sub Gateway { my $Subject = $head->get('Subject') || ''; chomp $Subject; - $args{'ticket'} ||= $parser->ParseTicketId($Subject); my $SystemTicket; - if ($args{'ticket'} ) { + if ( $args{'ticket'} ) { $SystemTicket = RT::Ticket->new($RT::SystemUser); - $SystemTicket->Load($args{'ticket'}); + $SystemTicket->Load( $args{'ticket'} ); } #Set up a queue object my $SystemQueueObj = RT::Queue->new($RT::SystemUser); $SystemQueueObj->Load( $args{'queue'} ); - # We can safely have no queue of we have a known-good ticket unless ( $args{'ticket'} || $SystemQueueObj->id ) { - MailError( - To => $RT::OwnerEmail, - Subject => "RT Bounce: $Subject", - Explanation => "RT couldn't find the queue: " . $args{'queue'}, - MIMEObj => $Message ); - return ( 0, "RT couldn't find the queue: " . $args{'queue'}, undef ); + return ( -75, "RT couldn't find the queue: " . $args{'queue'}, undef ); } # Authentication Level - # -1 - Get out. this user has been explicitly declined + # -1 - Get out. this user has been explicitly declined # 0 - User may not do anything (Not used at the moment) # 1 - Normal user # 2 - User is allowed to specify status updates etc. a la enhanced-mailgate - push @RT::MailPlugins, "Auth::MailFrom" unless @RT::MailPlugins; + push @RT::MailPlugins, "Auth::MailFrom" unless @RT::MailPlugins; + # Since this needs loading, no matter what for (@RT::MailPlugins) { @@ -453,35 +520,59 @@ sub Gateway { } } - ( $CurrentUser, $NewAuthStat ) = $Code->( Message => $Message, - CurrentUser => $CurrentUser, - AuthLevel => $AuthStat, - Action => $args{'action'}, - Ticket => $SystemTicket, - Queue => $SystemQueueObj ); + ( $CurrentUser, $NewAuthStat ) = $Code->( + Message => $Message, + CurrentUser => $CurrentUser, + AuthLevel => $AuthStat, + Action => $args{'action'}, + Ticket => $SystemTicket, + Queue => $SystemQueueObj + ); + + # If a module returns a "-1" then we discard the ticket, so. + $AuthStat = -1 if $NewAuthStat == -1; # You get the highest level of authentication you were assigned. - last if $AuthStat == -1; $AuthStat = $NewAuthStat if $NewAuthStat > $AuthStat; + last if $AuthStat == -1; } # {{{ If authentication fails and no new user was created, get out. if ( !$CurrentUser or !$CurrentUser->Id or $AuthStat == -1 ) { # If the plugins refused to create one, they lose. - MailError( - Subject => "Could not load a valid user", - Explanation => <<EOT, + unless ( $AuthStat == -1 ) { + + # Notify the RT Admin of the failure. + # XXX Should this be configurable? + MailError( + To => $RT::OwnerEmail, + Subject => "Could not load a valid user", + Explanation => <<EOT, RT could not load a valid user, and RT's configuration does not allow -for the creation of a new user for your email. +for the creation of a new user for this email ($ErrorsTo). -Your RT administrator needs to grant 'Everyone' the right 'CreateTicket' -for this queue. +You might need to grant 'Everyone' the right 'CreateTicket' for the +queue @{[$args{'queue'}]}. EOT - MIMEObj => $Message, - LogLevel => 'error' ) - unless $AuthStat == -1; + MIMEObj => $Message, + LogLevel => 'error' + ); + + # Also notify the requestor that his request has been dropped. + MailError( + To => $ErrorsTo, + Subject => "Could not load a valid user", + Explanation => <<EOT, +RT could not load a valid user, and RT's configuration does not allow +for the creation of a new user for your email. + +EOT + MIMEObj => $Message, + LogLevel => 'error' + ); + } return ( 0, "Could not load a valid user", undef ); } @@ -508,10 +599,11 @@ EOT # {{{ Drop it if it's disallowed if ( $AuthStat == 0 ) { MailError( - To => $ErrorsTo, - Subject => "Permission Denied", - Explanation => "You do not have permission to communicate with RT", - MIMEObj => $Message ); + To => $ErrorsTo, + Subject => "Permission Denied", + Explanation => "You do not have permission to communicate with RT", + MIMEObj => $Message + ); } # }}} @@ -523,10 +615,12 @@ EOT #Should we mail it to RTOwner? if ($RT::LoopsToRTOwner) { - MailError( To => $RT::OwnerEmail, - Subject => "RT Bounce: $Subject", - Explanation => "RT thinks this message may be a bounce", - MIMEObj => $Message ); + MailError( + To => $RT::OwnerEmail, + Subject => "RT Bounce: $Subject", + Explanation => "RT thinks this message may be a bounce", + MIMEObj => $Message + ); #Do we actually want to store it? return ( 0, "Message Bounced", undef ) unless ($RT::StoreLoops); @@ -538,8 +632,10 @@ EOT # {{{ Squelch replies if necessary # Don't let the user stuff the RT-Squelch-Replies-To header. if ( $head->get('RT-Squelch-Replies-To') ) { - $head->add( 'RT-Relocated-Squelch-Replies-To', - $head->get('RT-Squelch-Replies-To') ); + $head->add( + 'RT-Relocated-Squelch-Replies-To', + $head->get('RT-Squelch-Replies-To') + ); $head->delete('RT-Squelch-Replies-To'); } @@ -564,22 +660,27 @@ EOT my @Requestors = ( $CurrentUser->id ); if ($RT::ParseNewMessageForTicketCcs) { - @Cc = ParseCcAddressesFromHead( Head => $head, - CurrentUser => $CurrentUser, - QueueObj => $SystemQueueObj ); + @Cc = ParseCcAddressesFromHead( + Head => $head, + CurrentUser => $CurrentUser, + QueueObj => $SystemQueueObj + ); } my ( $id, $Transaction, $ErrStr ) = $Ticket->Create( - Queue => $SystemQueueObj->Id, - Subject => $Subject, - Requestor => \@Requestors, - Cc => \@Cc, - MIMEObj => $Message ); + Queue => $SystemQueueObj->Id, + Subject => $Subject, + Requestor => \@Requestors, + Cc => \@Cc, + MIMEObj => $Message + ); if ( $id == 0 ) { - MailError( To => $ErrorsTo, - Subject => "Ticket creation failed", - Explanation => $ErrStr, - MIMEObj => $Message ); + MailError( + To => $ErrorsTo, + Subject => "Ticket creation failed", + Explanation => $ErrStr, + MIMEObj => $Message + ); $RT::Logger->error("Create failed: $id / $Transaction / $ErrStr "); return ( 0, "Ticket creation failed", $Ticket ); } @@ -591,15 +692,17 @@ EOT # If the action is comment, add a comment. elsif ( $args{'action'} =~ /^(comment|correspond)$/i ) { - $Ticket->Load($args{'ticket'}); + $Ticket->Load( $args{'ticket'} ); unless ( $Ticket->Id ) { - my $message = "Could not find a ticket with id ".$args{'ticket'}; - MailError( To => $ErrorsTo, - Subject => "Message not recorded", - Explanation => $message, - MIMEObj => $Message ); - - return ( 0, $message); + my $message = "Could not find a ticket with id " . $args{'ticket'}; + MailError( + To => $ErrorsTo, + Subject => "Message not recorded", + Explanation => $message, + MIMEObj => $Message + ); + + return ( 0, $message ); } my ( $status, $msg ); @@ -612,10 +715,12 @@ EOT unless ($status) { #Warn the sender that we couldn't actually submit the comment. - MailError( To => $ErrorsTo, - Subject => "Message not recorded", - Explanation => $msg, - MIMEObj => $Message ); + MailError( + To => $ErrorsTo, + Subject => "Message not recorded", + Explanation => $msg, + MIMEObj => $Message + ); return ( 0, "Message not recorded", $Ticket ); } } @@ -623,21 +728,28 @@ EOT else { #Return mail to the sender with an error - MailError( To => $ErrorsTo, - Subject => "RT Configuration error", - Explanation => "'" - . $args{'action'} - . "' not a recognized action." - . " Your RT administrator has misconfigured " - . "the mail aliases which invoke RT", - MIMEObj => $Message ); + MailError( + To => $ErrorsTo, + Subject => "RT Configuration error", + Explanation => "'" + . $args{'action'} + . "' not a recognized action." + . " Your RT administrator has misconfigured " + . "the mail aliases which invoke RT", + MIMEObj => $Message + ); $RT::Logger->crit( $args{'action'} . " type unknown for $MessageId" ); - return ( 0, "Configuration error: " . $args{'action'} . " not a recognized action", $Ticket ); + return ( + -75, + "Configuration error: " + . $args{'action'} + . " not a recognized action", + $Ticket + ); } - -return ( 1, "Success", $Ticket ); + return ( 1, "Success", $Ticket ); } eval "require RT::Interface::Email_Vendor"; diff --git a/rt/lib/RT/Interface/REST.pm b/rt/lib/RT/Interface/REST.pm new file mode 100644 index 000000000..1ec4f21f9 --- /dev/null +++ b/rt/lib/RT/Interface/REST.pm @@ -0,0 +1,252 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK +# lib/RT/Interface/REST.pm +# + +package RT::Interface::REST; +use strict; +use RT; + +BEGIN { + use Exporter (); + use vars qw($VERSION @ISA @EXPORT); + + $VERSION = do { my @r = (q$Revision: 1.1 $ =~ /\d+/g); sprintf "%d."."%02d"x$#r, @r }; + + @ISA = qw(Exporter); + @EXPORT = qw(expand_list form_parse form_compose vpush vsplit); +} + +my $field = '[a-zA-Z][a-zA-Z0-9_-]*'; + +sub expand_list { + my ($list) = @_; + my ($elt, @elts, %elts); + + foreach $elt (split /,/, $list) { + if ($elt =~ /^(\d+)-(\d+)$/) { push @elts, ($1..$2) } + else { push @elts, $elt } + } + + @elts{@elts}=(); + return sort {$a<=>$b} keys %elts; +} + +# Returns a reference to an array of parsed forms. +sub form_parse { + my $state = 0; + my @forms = (); + my @lines = split /\n/, $_[0]; + my ($c, $o, $k, $e) = ("", [], {}, ""); + + LINE: + while (@lines) { + my $line = shift @lines; + + next LINE if $line eq ''; + + if ($line eq '--') { + # We reached the end of one form. We'll ignore it if it was + # empty, and store it otherwise, errors and all. + if ($e || $c || @$o) { + push @forms, [ $c, $o, $k, $e ]; + $c = ""; $o = []; $k = {}; $e = ""; + } + $state = 0; + } + elsif ($state != -1) { + if ($state == 0 && $line =~ /^#/) { + # Read an optional block of comments (only) at the start + # of the form. + $state = 1; + $c = $line; + while (@lines && $lines[0] =~ /^#/) { + $c .= "\n".shift @lines; + } + $c .= "\n"; + } + elsif ($state <= 1 && $line =~ /^($field):(?:\s+(.*))?$/) { + # Read a field: value specification. + my $f = $1; + my @v = ($2 || ()); + + # Read continuation lines, if any. + while (@lines && ($lines[0] eq '' || $lines[0] =~ /^\s+/)) { + push @v, shift @lines; + } + pop @v while (@v && $v[-1] eq ''); + + # Strip longest common leading indent from text. + my ($ws, $ls) = (""); + foreach $ls (map {/^(\s+)/} @v[1..$#v]) { + $ws = $ls if (!$ws || length($ls) < length($ws)); + } + s/^$ws// foreach @v; + + push(@$o, $f) unless exists $k->{$f}; + vpush($k, $f, join("\n", @v)); + + $state = 1; + } + elsif ($line !~ /^#/) { + # We've found a syntax error, so we'll reconstruct the + # form parsed thus far, and add an error marker. (>>) + $state = -1; + $e = form_compose([[ "", $o, $k, "" ]]); + $e.= $line =~ /^>>/ ? "$line\n" : ">> $line\n"; + } + } + else { + # We saw a syntax error earlier, so we'll accumulate the + # contents of this form until the end. + $e .= "$line\n"; + } + } + push(@forms, [ $c, $o, $k, $e ]) if ($e || $c || @$o); + + my $l; + foreach $l (keys %$k) { + $k->{$l} = vsplit($k->{$l}) if (ref $k->{$l} eq 'ARRAY'); + } + + return \@forms; +} + +# Returns text representing a set of forms. +sub form_compose { + my ($forms) = @_; + my (@text, $form); + + foreach $form (@$forms) { + my ($c, $o, $k, $e) = @$form; + my $text = ""; + + if ($c) { + $c =~ s/\n*$/\n/; + $text = "$c\n"; + } + if ($e) { + $text .= $e; + } + elsif ($o) { + my (@lines, $key); + + foreach $key (@$o) { + my ($line, $sp, $v); + my @values = (ref $k->{$key} eq 'ARRAY') ? + @{ $k->{$key} } : + $k->{$key}; + + $sp = " "x(length("$key: ")); + $sp = " "x4 if length($sp) > 16; + + foreach $v (@values) { + if ($v =~ /\n/) { + $v =~ s/^/$sp/gm; + $v =~ s/^$sp//; + + if ($line) { + push @lines, "$line\n\n"; + $line = ""; + } + elsif (@lines && $lines[-1] !~ /\n\n$/) { + $lines[-1] .= "\n"; + } + push @lines, "$key: $v\n\n"; + } + elsif ($line && + length($line)+length($v)-rindex($line, "\n") >= 70) + { + $line .= ",\n$sp$v"; + } + else { + $line = $line ? "$line, $v" : "$key: $v"; + } + } + + $line = "$key:" unless @values; + if ($line) { + if ($line =~ /\n/) { + if (@lines && $lines[-1] !~ /\n\n$/) { + $lines[-1] .= "\n"; + } + $line .= "\n"; + } + push @lines, "$line\n"; + } + } + + $text .= join "", @lines; + } + else { + chomp $text; + } + push @text, $text; + } + + return join "\n--\n\n", @text; +} + +# Add a value to a (possibly multi-valued) hash key. +sub vpush { + my ($hash, $key, $val) = @_; + my @val = ref $val eq 'ARRAY' ? @$val : $val; + + if (exists $hash->{$key}) { + unless (ref $hash->{$key} eq 'ARRAY') { + my @v = $hash->{$key} ne '' ? $hash->{$key} : (); + $hash->{$key} = \@v; + } + push @{ $hash->{$key} }, @val; + } + else { + $hash->{$key} = $val; + } +} + +# "Normalise" a hash key that's known to be multi-valued. +sub vsplit { + my ($val) = @_; + my ($line, $word, @words); + + foreach $line (map {split /\n/} (ref $val eq 'ARRAY') ? @$val : $val) + { + # XXX: This should become a real parser, à la Text::ParseWords. + $line =~ s/^\s+//; + $line =~ s/\s+$//; + push @words, split /\s*,\s*/, $line; + } + + return \@words; +} + +1; + +=head1 NAME + + RT::Interface::REST - helper functions for the REST interface. + +=head1 SYNOPSIS + + Only the REST should use this module. diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm index 5097f54a4..8d66239be 100644 --- a/rt/lib/RT/Interface/Web.pm +++ b/rt/lib/RT/Interface/Web.pm @@ -68,6 +68,7 @@ sub NewApacheHandler { default_escape_flags => 'h', allow_globals => [qw(%session)], data_dir => "$RT::MasonDataDir", + autoflush => 1, @_ ); @@ -98,7 +99,8 @@ sub NewCGIHandler { ], data_dir => "$RT::MasonDataDir", default_escape_flags => 'h', - allow_globals => [qw(%session)] + allow_globals => [qw(%session)], + autoflush => 1, ); @@ -137,6 +139,60 @@ sub EscapeUTF8 { # }}} +# {{{ WebCanonicalizeInfo + +=head2 WebCanonicalizeInfo(); + +Different web servers set different environmental varibles. This +function must return something suitable for REMOTE_USER. By default, +just downcase $ENV{'REMOTE_USER'} + +=cut + +sub WebCanonicalizeInfo { + my $user; + + if ( defined $ENV{'REMOTE_USER'} ) { + $user = lc ( $ENV{'REMOTE_USER'} ) if( length($ENV{'REMOTE_USER'}) ); + } + + return $user; +} + +# }}} + +# {{{ WebExternalAutoInfo + +=head2 WebExternalAutoInfo($user); + +Returns a hash of user attributes, used when WebExternalAuto is set. + +=cut + +sub WebExternalAutoInfo { + my $user = shift; + + my %user_info; + + $user_info{'Privileged'} = 1; + + if ($^O !~ /^(?:riscos|MacOS|MSWin32|dos|os2)$/) { + # Populate fields with information from Unix /etc/passwd + + my ($comments, $realname) = (getpwnam($user))[5, 6]; + $user_info{'Comments'} = $comments if defined $comments; + $user_info{'RealName'} = $realname if defined $realname; + } + elsif ($^O eq 'MSWin32' and eval 'use Net::AdminMisc; 1') { + # Populate fields with information from NT domain controller + } + + # and return the wad of stuff + return {%user_info}; +} + +# }}} + package HTML::Mason::Commands; use strict; @@ -160,10 +216,13 @@ sub loc { UNIVERSAL::can($session{'CurrentUser'}, 'loc')){ return($session{'CurrentUser'}->loc(@_)); } - else { - my $u = RT::CurrentUser->new($RT::SystemUser); + elsif ( my $u = eval { RT::CurrentUser->new($RT::SystemUser->Id) } ) { return ($u->loc(@_)); } + else { + # pathetic case -- SystemUser is gone. + return $_[0]; + } } # }}} @@ -189,7 +248,7 @@ sub loc_fuzzy { return($session{'CurrentUser'}->loc_fuzzy($msg)); } else { - my $u = RT::CurrentUser->new($RT::SystemUser); + my $u = RT::CurrentUser->new($RT::SystemUser->Id); return ($u->loc_fuzzy($msg)); } } @@ -365,7 +424,8 @@ sub ProcessUpdateMessage { ); #Make the update content have no 'weird' newlines in it - if ( $args{ARGSRef}->{'UpdateContent'} ) { + if ( $args{ARGSRef}->{'UpdateContent'} || + $args{ARGSRef}->{'UpdateAttachments'}) { if ( $args{ARGSRef}->{'UpdateSubject'} eq $args{'TicketObj'}->Subject() ) @@ -433,7 +493,8 @@ sub MakeMIMEEntity { Cc => undef, Body => undef, AttachmentFieldName => undef, - map Encode::encode_utf8($_), @_, +# map Encode::encode_utf8($_), @_, + @_, ); #Make the update content have no 'weird' newlines in it @@ -449,6 +510,7 @@ sub MakeMIMEEntity { Subject => $args{'Subject'} || "", From => $args{'From'}, Cc => $args{'Cc'}, + Charset => 'utf8', Data => [ $args{'Body'} ] ); } @@ -463,7 +525,14 @@ sub MakeMIMEEntity { #foreach my $filehandle (@filenames) { - my ( $fh, $temp_file ) = tempfile(); + my ( $fh, $temp_file ); + for ( 1 .. 10 ) { + # on NFS and NTFS, it is possible that tempfile() conflicts + # with other processes, causing a race condition. we try to + # accommodate this by pausing and retrying. + last if ($fh, $temp_file) = eval { tempfile() }; + sleep 1; + } binmode $fh; #thank you, windows my ($buffer); @@ -481,7 +550,7 @@ sub MakeMIMEEntity { $Message->attach( Path => $temp_file, - Filename => $filename, + Filename => Encode::decode_utf8($filename), Type => $uploadinfo->{'Content-Type'}, ); close($fh); @@ -594,13 +663,13 @@ sub ProcessSearchQuery { # }}} # {{{ Limit requestor email + if ( $args{ARGS}->{'ValueOfWatcherRole'} ne '' ) { + $session{'tickets'}->LimitWatcher( + TYPE => $args{ARGS}->{'WatcherRole'}, + VALUE => $args{ARGS}->{'ValueOfWatcherRole'}, + OPERATOR => $args{ARGS}->{'WatcherRoleOp'}, - if ( $args{ARGS}->{'ValueOfRequestor'} ne '' ) { - my $alias = $session{'tickets'}->LimitRequestor( - VALUE => $args{ARGS}->{'ValueOfRequestor'}, - OPERATOR => $args{ARGS}->{'RequestorOp'}, ); - } # }}} @@ -780,17 +849,13 @@ sub ProcessACLChanges { my $obj; - if ($object_type eq 'RT::Queue') { - $obj = RT::Queue->new($session{'CurrentUser'}); - $obj->Load($object_id); - } elsif ($object_type eq 'RT::Group') { - $obj = RT::Group->new($session{'CurrentUser'}); - $obj->Load($object_id); - - } elsif ($object_type eq 'RT::System') { + if ($object_type eq 'RT::System') { $obj = $RT::System; + } elsif ($RT::ACE::OBJECT_TYPES{$object_type}) { + $obj = $object_type->new($session{'CurrentUser'}); + $obj->Load($object_id); } else { - push (@results, loc("System Error"). + push (@results, loc("System Error"). ': '. loc("Rights could not be granted for [_1]", $object_type)); next; } @@ -813,17 +878,14 @@ sub ProcessACLChanges { next unless ($right); my $obj; - if ($object_type eq 'RT::Queue') { - $obj = RT::Queue->new($session{'CurrentUser'}); - $obj->Load($object_id); - } elsif ($object_type eq 'RT::Group') { - $obj = RT::Group->new($session{'CurrentUser'}); - $obj->Load($object_id); - - } elsif ($object_type eq 'RT::System') { + if ($object_type eq 'RT::System') { $obj = $RT::System; + } elsif ($RT::ACE::OBJECT_TYPES{$object_type}) { + $obj = $object_type->new($session{'CurrentUser'}); + $obj->Load($object_id); } else { - push (@results, loc("System Error"). + die; + push (@results, loc("System Error"). ': '. loc("Rights could not be revoked for [_1]", $object_type)); next; } @@ -953,6 +1015,17 @@ sub ProcessCustomFieldUpdates { my ( $err, $msg ) = $Object->DeleteValue($id); push ( @results, $msg ); } + + my $vals = $Object->Values(); + while (my $cfv = $vals->Next()) { + if (my $so = $ARGSRef->{ 'CustomField-' . $Object->Id . '-SortOrder' . $cfv->Id }) { + if ($cfv->SortOrder != $so) { + my ( $err, $msg ) = $cfv->SetSortOrder($so); + push ( @results, $msg ); + } + } + } + return (@results); } @@ -1050,8 +1123,11 @@ sub ProcessTicketCustomFieldUpdates { # For each of those tickets foreach my $tick ( keys %custom_fields_to_mod ) { - my $Ticket = RT::Ticket->new( $session{'CurrentUser'} ); - $Ticket->Load($tick); + my $Ticket = $args{'TicketObj'}; + if (!$Ticket or $Ticket->id != $tick) { + $Ticket = RT::Ticket->new( $session{'CurrentUser'} ); + $Ticket->Load($tick); + } # For each custom field foreach my $cf ( keys %{ $custom_fields_to_mod{$tick} } ) { @@ -1074,10 +1150,10 @@ sub ProcessTicketCustomFieldUpdates { my @values = ( ref( $ARGSRef->{$arg} ) eq 'ARRAY' ) ? @{ $ARGSRef->{$arg} } - : ( $ARGSRef->{$arg} ); + : split /\n/, $ARGSRef->{$arg} ; if ( ( $arg =~ /-AddValue$/ ) || ( $arg =~ /-Value$/ ) ) { foreach my $value (@values) { - next unless ($value); + next unless length($value); my ( $val, $msg ) = $Ticket->AddCustomFieldValue( Field => $cf, Value => $value @@ -1087,7 +1163,7 @@ sub ProcessTicketCustomFieldUpdates { } elsif ( $arg =~ /-DeleteValues$/ ) { foreach my $value (@values) { - next unless ($value); + next unless length($value); my ( $val, $msg ) = $Ticket->DeleteCustomFieldValue( Field => $cf, Value => $value @@ -1100,7 +1176,7 @@ sub ProcessTicketCustomFieldUpdates { my %values_hash; foreach my $value (@values) { - next unless ($value); + next unless length($value); # build up a hash of values that the new set has $values_hash{$value} = 1; diff --git a/rt/lib/RT/Principal_Overlay.pm b/rt/lib/RT/Principal_Overlay.pm index d2782b730..b788e36c4 100644 --- a/rt/lib/RT/Principal_Overlay.pm +++ b/rt/lib/RT/Principal_Overlay.pm @@ -348,6 +348,12 @@ sub HasRight { next unless (UNIVERSAL::can($obj, 'id')); my $type = ref($obj); my $id = $obj->id; + + unless ($id) { + use Carp; + Carp::cluck("Trying to check $type rights for an unspecified $type"); + $RT::Logger->crit("Trying to check $type rights for an unspecified $type"); + } push @look_at_objects, "(ACL.ObjectType = '$type' AND ACL.ObjectId = '$id')"; } @@ -385,7 +391,8 @@ sub HasRight { "AND ( ( ACL.PrincipalId = Principals.id AND ACL.PrincipalType = 'Group' AND ". "(Groups.Domain = 'SystemInternal' OR Groups.Domain = 'UserDefined' OR Groups.Domain = 'ACLEquivalence' OR Groups.Domain = 'Personal'))". - " ) LIMIT 1"; + " ) "; + $self->_Handle->ApplyLimits(\$groups_query, 1); #only return one result my @roles; foreach my $object (@{$args{'EquivObjects'}}) { @@ -397,7 +404,8 @@ sub HasRight { if (@roles) { $roles_query = $query_base . "AND ". " ( (".join (' OR ', @roles)." ) ". - " AND Groups.Type = ACL.PrincipalType AND Groups.Id = Principals.id AND Principals.PrincipalType = 'Group') LIMIT 1"; + " AND Groups.Type = ACL.PrincipalType AND Groups.Id = Principals.id AND Principals.PrincipalType = 'Group') "; + $self->_Handle->ApplyLimits(\$roles_query, 1); #only return one result } @@ -461,7 +469,18 @@ sub _RolesForObject { my $self = shift; my $type = shift; my $id = shift; - my $clause = "(Groups.Domain = '".$type."-Role' AND Groups.Instance = '" . $id. "') "; + + unless ($id) { + $id = '0'; + } + + # This should never be true. + unless ($id =~ /^\d+$/) { + $RT::Logger->crit("RT::Prinicipal::_RolesForObject called with type $type and a non-integer id: '$id'"); + $id = "'$id'"; + } + + my $clause = "(Groups.Domain = '".$type."-Role' AND Groups.Instance = $id) "; return($clause); } diff --git a/rt/lib/RT/Queue_Overlay.pm b/rt/lib/RT/Queue_Overlay.pm index 4eb265f2a..fcc185b10 100644 --- a/rt/lib/RT/Queue_Overlay.pm +++ b/rt/lib/RT/Queue_Overlay.pm @@ -327,7 +327,7 @@ sub Load { $self->SUPER::LoadById($identifier); } else { - $self->LoadByCol( "Name", $identifier ); + $self->LoadByCols( Name => $identifier ); } return ( $self->Id ); @@ -866,8 +866,11 @@ sub IsWatcher { my $principal = RT::Principal->new($self->CurrentUser); $principal->Load($args{'PrincipalId'}); + unless ($principal->Id) { + return (undef); + } - return ($group->HasMember($principal)); + return ($group->HasMemberRecursively($principal)); } # }}} diff --git a/rt/lib/RT/Record.pm b/rt/lib/RT/Record.pm index 6962221ea..7a8690618 100755 --- a/rt/lib/RT/Record.pm +++ b/rt/lib/RT/Record.pm @@ -211,7 +211,10 @@ sub LoadByCols { $newhash{$key} = $hash{$key}; } else { - $newhash{ "lower(" . $key . ")" } = lc( $hash{$key} ); + my ($op, $val); + ($key, $op, $val) = $self->_Handle->_MakeClauseCaseInsensitive($key, '=', $hash{$key}); + $newhash{$key}->{operator} = $op; + $newhash{$key}->{value} = $val; } } diff --git a/rt/lib/RT/ScripAction_Overlay.pm b/rt/lib/RT/ScripAction_Overlay.pm index e2b018aaf..e75987135 100644 --- a/rt/lib/RT/ScripAction_Overlay.pm +++ b/rt/lib/RT/ScripAction_Overlay.pm @@ -48,6 +48,7 @@ ok (require RT::ScripAction); use strict; no warnings qw(redefine); +use RT::Template; # {{{ sub _Init sub _Init { @@ -135,6 +136,8 @@ sub LoadAction { my %args = ( TransactionObj => undef, TicketObj => undef, @_ ); + + $self->{_TicketObj} = $args{TicketObj}; #TODO: Put this in an eval $self->ExecModule =~ /^(\w+)$/; @@ -164,14 +167,26 @@ Return this action\'s template object sub TemplateObj { my $self = shift; return undef unless $self->{Template}; - if (!$self->{'TemplateObj'}) { - require RT::Template; - $self->{'TemplateObj'} = RT::Template->new($self->CurrentUser); - $self->{'TemplateObj'}->LoadById($self->{'Template'}); - + if ( !$self->{'TemplateObj'} ) { + $self->{'TemplateObj'} = RT::Template->new( $self->CurrentUser ); + $self->{'TemplateObj'}->LoadById( $self->{'Template'} ); + + if ( ( $self->{'TemplateObj'}->__Value('Queue') == 0 ) + && $self->{'_TicketObj'} ) { + my $tmptemplate = RT::Template->new( $self->CurrentUser ); + my ( $ok, $err ) = $tmptemplate->LoadQueueTemplate( + Queue => $self->{'_TicketObj'}->QueueObj->id, + Name => $self->{'TemplateObj'}->Name); + + if ( $tmptemplate->id ) { + # found the queue-specific template with the same name + $self->{'TemplateObj'} = $tmptemplate; + } + } + } - - return ($self->{'TemplateObj'}); + + return ( $self->{'TemplateObj'} ); } # }}} @@ -206,6 +221,7 @@ sub Describe { # {{{ sub DESTROY sub DESTROY { my $self=shift; + $self->{'_TicketObj'} = undef; $self->{'Action'} = undef; $self->{'TemplateObj'} = undef; } diff --git a/rt/lib/RT/Scrip_Overlay.pm b/rt/lib/RT/Scrip_Overlay.pm index 06462a9ac..4f6c735cc 100644 --- a/rt/lib/RT/Scrip_Overlay.pm +++ b/rt/lib/RT/Scrip_Overlay.pm @@ -142,19 +142,24 @@ sub Create { require RT::ScripAction; my $action = new RT::ScripAction( $self->CurrentUser ); - $action->Load( $args{'ScripAction'} || '0' ); + if ($args{'ScripAction'}) { + $action->Load( $args{'ScripAction'}); + } return ( 0, $self->loc( "Action [_1] not found", $args{'ScripAction'} ) ) unless $action->Id; require RT::Template; my $template = new RT::Template( $self->CurrentUser ); - $template->Load( $args{'Template'}||'0' ); + if ($args{'Template'} ) { + $template->Load( $args{'Template'}); + } return ( 0, $self->loc('Template not found') ) unless $template->Id; require RT::ScripCondition; my $condition = new RT::ScripCondition( $self->CurrentUser ); - $condition->Load( $args{'ScripCondition'}||'0' ); - + if ($args{'ScripCondition'} ) { + $condition->Load( $args{'ScripCondition'} ); + } unless ( $condition->Id ) { return ( 0, $self->loc('Condition not found') ); } @@ -256,13 +261,16 @@ Retuns an RT::ScripCondition object with this Scrip's IsApplicable sub ConditionObj { my $self = shift; - - unless (defined $self->{'ScripConditionObj'}) { - require RT::ScripCondition; - $self->{'ScripConditionObj'} = RT::ScripCondition->new($self->CurrentUser); - $self->{'ScripConditionObj'}->Load($self->ScripCondition); + + unless ( defined $self->{'ScripConditionObj'} ) { + require RT::ScripCondition; + $self->{'ScripConditionObj'} = + RT::ScripCondition->new( $self->CurrentUser ); + if ( $self->ScripCondition ) { + $self->{'ScripConditionObj'}->Load( $self->ScripCondition ); + } } - return ($self->{'ScripConditionObj'}); + return ( $self->{'ScripConditionObj'} ); } # }}} diff --git a/rt/lib/RT/Scrips_Overlay.pm b/rt/lib/RT/Scrips_Overlay.pm index 46e31c2a8..d20148084 100644 --- a/rt/lib/RT/Scrips_Overlay.pm +++ b/rt/lib/RT/Scrips_Overlay.pm @@ -129,5 +129,80 @@ sub Next { } # }}} +sub Apply { + my ($self, %args) = @_; + + #We're really going to need a non-acled ticket for the scrips to work + my ($TicketObj, $TransactionObj); + + if ( ($TicketObj = $args{'TicketObj'}) ) { + $TicketObj->CurrentUser($self->CurrentUser); + } + else { + $TicketObj = RT::Ticket->new($self->CurrentUser); + $TicketObj->Load( $args{'Ticket'} ) + || $RT::Logger->err("$self couldn't load ticket $args{'Ticket'}\n"); + } + + if ( ($TransactionObj = $args{'TransactionObj'}) ) { + $TransactionObj->CurrentUser($self->CurrentUser); + } + else { + $TransactionObj = RT::Transaction->new($self->CurrentUser); + $TransactionObj->Load( $args{'Transaction'} ) + || $RT::Logger->err("$self couldn't load transaction $args{'Transaction'}\n"); + } + + # {{{ Deal with Scrips + + $self->LimitToQueue( $TicketObj->QueueObj->Id ) + ; #Limit it to $Ticket->QueueObj->Id + $self->LimitToGlobal() + unless $TicketObj->QueueObj->Disabled; # or to "global" + + + $self->Limit(FIELD => "Stage", VALUE => $args{'Stage'}); + + + my $ConditionsAlias = $self->NewAlias('ScripConditions'); + + $self->Join( + ALIAS1 => 'main', + FIELD1 => 'ScripCondition', + ALIAS2 => $ConditionsAlias, + FIELD2 => 'id' + ); + + #We only want things where the scrip applies to this sort of transaction + $self->Limit( + ALIAS => $ConditionsAlias, + FIELD => 'ApplicableTransTypes', + OPERATOR => 'LIKE', + VALUE => $args{'Type'}, + ENTRYAGGREGATOR => 'OR', + ) if $args{'Type'}; + + # Or where the scrip applies to any transaction + $self->Limit( + ALIAS => $ConditionsAlias, + FIELD => 'ApplicableTransTypes', + OPERATOR => 'LIKE', + VALUE => "Any", + ENTRYAGGREGATOR => 'OR', + ); + + #Iterate through each script and check it's applicability. + while ( my $Scrip = $self->Next() ) { + $Scrip->Apply (TicketObj => $TicketObj, + TransactionObj => $TransactionObj); + } + + $TicketObj->CurrentUser( $TicketObj->OriginalUser ); + $TransactionObj->CurrentUser( $TransactionObj->OriginalUser ); + + # }}} +} + + 1; diff --git a/rt/lib/RT/StyleGuide.pod b/rt/lib/RT/StyleGuide.pod new file mode 100644 index 000000000..95b2e3a15 --- /dev/null +++ b/rt/lib/RT/StyleGuide.pod @@ -0,0 +1,891 @@ +=head1 NAME + +RT::StyleGuide - RT Style Guide + +=head1 INTRODUCTION + +All code and documentation that is submitted to be included in the RT +distribution should follow the style in this document. This is not to +try to stifle your creativity, but to make life easier for everybody who +has to work with your code, and to aid those who are not quite sure how +to do something. + +These conventions below apply to perl modules, web programs, and +command-line programs, specifically, but also might apply to some +degree to any Perl code written for use in RT. + +Note that these are all guidelines, not unbreakable rules. If you have +a really good need to break one of the rules herein, however, then it is +best to ask on the B<rt-devel> mailing list first. + +Note that with much of this document, it is not so much the Right Way as +it is Our Way. We need to have conventions in order to make life easier +for everyone. So don't gripe, and just follow it, because you didn't +get a good grade in "Plays Well With Others" in kindergarten and you +want to make up for it now. + +If you have any questions, please ask us on the B<rt-devel> mailing list: + + http://www.bestpractical.com/rt/lists.html + +We don't always follow this guide. We are making changes throughout +our code to be in line with it. But just because we didn't do +it yet, that is no excuse. Do it anyway. :-) + +This document is subject to change at the whims of the core RT team. +We hope to add any significant changes at the bottom of the document. + + +=head1 CODING PRINCIPLES + +=head2 Perl Version + +We code everything to perl 5.6.1. Some features require advanced unicode +features in perl 5.8.0. It is acceptable that unicode features work only for +US-ASCII on perl 5.6.1. + + +=head2 Documentation + +All modules will be documented using the POD examples in the module +boilerplate. The function, purpose, use of the module will be +explained, and each public API will be documented with name, +description, inputs, outputs, side effects, etc. + +If an array or hash reference is returned, document the size of the +array (including what each element is, as appropriate) and name each key +in the hash. For complex data structures, map out the structure as +appropriate (e.g., name each field returned for each column from a DB +call; yes, this means you shouldn't use "SELECT *", which you shouldn't +use anyway). + +Also document what kind of data returned values are. Is it an integer, +a block of HTML, a boolean? + +All command-line program options will be documented using the +boilerplate code for command-line programs, which doesn't yet exist. +Each available function, switch, etc. should be documented, along +with a statement of function, purpose, use of the program. Do not +use the same options as another program, for a different purpose. + +All web templates should be documented with a statement of function, +purpose, and use in a mason comment block. + +Any external documents, and documentation for command-line programs and +modules, should be written in POD, where appropriate. From there, they +can be translated to many formats with the various pod2* translators. +Read the perlpod manpage before writing any POD, because although POD is +not difficult, it is not what most people are used to. It is not a +regular markup language; it is just a way to make easy documentation +for translating to other formats. Read, and understand, the perlpod +manpage, and ask us or someone else who knows if you have any questions. + + +=head2 Version + +Our distribution versions use tuples, where the first number is the +major revision, the second number is the version, and third +number is the subversion. Odd-numbered versions are development +versions. Examples: + + 1.0.0 First release of RT 1 + 1.0.1 Second release of RT 1.0 + 1.0.10 etc. + 1.1.0 First development release of RT 1.2 (or 2.0) + 2.0.0 First release of RT 2 + +Versions can be modified with a hyphen followed by some text, for +special versions, or to give extra information. Examples: + + 2.0.0-pre1 Notes that this is not final, but preview + +In perl 5.6.0, you can have versions like C<v2.0.0>, but this is not +allowed in previous versions of perl. So to convert a tuple version +string to a string to use with $VERSION, use a regular integer for +the revision, and three digits for version and subversion. Examples: + + 1.1.6 -> 1.001006 + 2.0.0 -> 2.000000 + +This way, perl can use the version strings in greater-than and +less-than comparisons. + + +=head2 Comments + +All code should be self-documenting as much as possible. Only include +necessary comments. Use names like "$ticket_count", so you don't need to +do something like: + + # ticket count + my $tc = 0; + +Include any comments that are, or might be, necessary in order for +someone else to understand the code. Sometimes a simple one-line +comment is good to explain what the purpose of the following code is +for. Sometimes each line needs to be commented because of a complex +algorithm. Read Kernighan & Pike's I<Practice of Programming> about +commenting. Good stuff, Maynard. + + +=head2 Warnings and Strict + +All code must compile and run cleanly with "use strict" enabled and the +perl "-w" (warnings) option on. If you must do something that -w or +strict complains about, there are workarounds, but the chances that you +really need to do it that way are remote. + +=head2 Lexical Variables + +Use only lexical variables, except for special global variables +($VERSION, %ENV, @ISA, $!, etc.) or very special circumstances (see +%HTML::Mason::Commands::session ). Global variables +for regular use are never appropriate. When necessary, "declare" +globals with "use vars" or "our()". + +A lexical variable is created with my(). A global variable is +pre-existing (if it is a special variable), or it pops into existence +when it is used. local() is used to tell perl to assign a temporary +value to a variable. This should only be used with special variables, +like $/, or in special circumstances. If you must assign to any global +variable, consider whether or not you should use local(). + +local() may also be used on elements of arrays and hashes, though there +is seldom a need to do it, and you shouldn't. + + +=head2 Exporting + +Do not export anything from a module by default. Feel free to put +anything you want to in @EXPORT_OK, so users of your modules can +explicitly ask for symbols (e.g., "use Something::Something qw(getFoo +setFoo)"), but do not export them by default. + + +=head2 Pass by Reference + +Arrays and hashes should be passed to and from functions by reference +only. Note that a list and an array are NOT the same thing. This +is perfectly fine: + + return($user, $form, $constants); + +An exception might be a temporary array of discrete arguments: + + my @return = ($user, $form); + push @return, $constants if $flag; + return @return; + +Although, usually, this is better (faster, easier to read, etc.): + + if ($flag) { + return($user, $form, $constants); + } else { + return($user, $form); + } + +We need to talk about Class::ReturnValue here. + + +=head2 Garbage Collection + +Perl does pretty good garbage collection for you. It will automatically +clean up lexical variables that have gone out of scope and objects whose +references have gone away. Normally you don't need to worry about +cleaning up after yourself, if using lexicals. + +However, some glue code, code compiled in C and linked to Perl, might +not automatically clean up for you. In such cases, clean up for +yourself. If there is a method in that glue to dispose or destruct, +then use it as appropriate. + +Also, if you have a long-running function that has a large data +structure in it, it is polite to free up the memory as soon as you are +done with it, if possible. + + my $huge_data_structure = get_huge_data_structure(); + do_something_with($huge_data_structure); + undef $huge_data_structure; + +=head2 DESTROY + +All object classes must provide a DESTROY method. If it won't do +anything, provide it anyway: + + sub DESTROY { } + + + +=head2 die() and exit() + +Don't do it. Do not die() or exit() from a web template or module. Do +not call C<kill 9, $$>. Don't do it. + +In command-line programs, do as you please. + + +=head2 shift and @_ + +Do not use @_. Use shift. shift may take more lines, but Jesse thinks it +leads to cleaner code. + + my $var = shift; # right + my($var) = @_; # ick. no + sub foo { uc $_[0] } # icky. sometimes ok. + + + my($var1, $var2) = (shift, shift); # Um, no. + + my $var1 = shift; # right + my $var2 = shift; + + + +=head2 Tests + +Modules should provide test code, with documentation on how to use +it. Test::Inline allows tests to be embedded in code. Test::More makes it +easy to create tests. Any code you write should have a testsuite. +Any code you alter should have a test suite. If a patch comes in without +tests, there is something wrong. + +When altering code, you must run the test harness before submitting a patch +or committing code to the repository. + +"make regression" will extract inline tests, blow away the system database +and run the test suite. + +"make regression-quiet" will do all that and not print the "ok" lines. + + + +=head2 STDIN/STDOUT + +Always report errors using $RT::Logger. It's a Log::Dispatch object. +Unlike message meant for the user, log messages are not to be +internationalized. + +There are several different levels ($RT::Logger methods) of logging: + +=over 4 + +=item debug + +Used for messages only needed during system debugging. + +=item info + +Should be used to describe "system-critical" events which aren't errors. +Examples: creating users, deleting users, creating tickets, creating queues, +sending email (message id, time, recipients), recieving mail, changing +passwords, changing access control, superuser logins) + +=item error + +Used for RT-generated failures during execution. + +=item crit + +Should be used for messages when an action can not be completed due to some +error condition beyond our control. + +=back + +In the web UI and modules, never print directly to STDERR. Do not print +directly to STDOUT, unless you need to print directly to the user's console. + +In command-line programs, feel free to print to STDERR and STDOUT as +needed for direct console communication. But for actual error reporting, +use the logging API. + + +=head2 System Calls + +Always check return values from system calls, including open(), +close(), mkdir(), or anything else that talks directly to the system. +Perl built-in system calls return the error in $!; some functions in +modules might return an error in $@ or some other way, so read the module's +documentation if you don't know. Always do something, even if it is +just calling $RT::Logger->warning(), when the return value is not what you'd expect. + + + +=head1 STYLE + +Much of the style section is taken from the perlsyle manpage. We make +some changes to it here, but it wouldn't be a bad idea to read that +document, too. + +=head2 Terminology + +=over 4 + +=item RT the name + +"RT" is the name of the project. "RT" is, optionally, the +specific name for the actual file distribution. That's it. + +While we sometimes use "RT2" or "RT3", that's shortand that's really +not recommended. The name of the project is "RT". + +To specify a major version, use "RT 3.0". +To specify a specific release, use "RT 3.0.12" + +=item function vs. sub(routine) vs. method + +Just because it is the Perl Way (not necessarily right for all +languages, but the documented terminology in the perl documentation), +"method" should be used only to refer to a subroutine that are object +methods or class methods; that is, these are functions that are used +with OOP that always take either an object or a class as the first +argument. Regular subroutines, ones that are not object or class +methods, are functions. Class methods that create and return an object +are optionally called constructors. + +=item Users + +"users" are normally users of RT, the ones hitting the site; if using +it in any other context, specify. +"system users" are user +names on the operating system. "database users" are the user names in +the database server. None of these needs to be capitalized. + +=back + + +=head2 Names + +Don't use single-character variables, except as iterator variables. + +Don't use two-character variables just to spite us over the above rule. + +Constants are in all caps; these are variables whose value will I<never> +change during the course of the program. + + $Minimum = 10; # wrong + $MAXIMUM = 50; # right + +Other variables are lowercase, with underscores separating the words. +They words used should, in general, form a noun (usually singular), +unless the variable is a flag used to denote some action that should be +taken, in which case they should be verbs (or gerunds, as appropriate) +describing that action. + + $thisVar = 'foo'; # wrong + $this_var = 'foo'; # right + $work_hard = 1; # right, verb, boolean flag + $running_fast = 0; # right, gerund, boolean flag + +Arrays and hashes should be plural nouns, whether as regular arrays and +hashes or array and hash references. Do not name references with "ref" +or the data type in the name. + + @stories = (1, 2, 3); # right + $comment_ref = [4, 5, 6]; # wrong + $comments = [4, 5, 6]; # right + $comment = $comments->[0]; # right + +Make the name descriptive. Don't use variables like "$sc" when you +could call it "$story_count". See L<"Comments">. + +There are several variables in RT that are used throughout the code, +that you should use in your code. Do not use these variable names for +anything other than how they are normally used, and do not use any +other variable names in their place. Some of these are: + + $self # first named argument in object method + +Subroutines (except for special cases, like AUTOLOAD and simple accessors) +begin with a verb, with words following to complete the action. Accessors +don't start with "Get" if they're just the name of the attribute. + +Accessors which return an object should end with the suffix Obj. + +This section needs clarification for RT. + +Words begin with a capital letter. They +should as clearly as possible describe the activity to be peformed, and +the data to be returned. + + + + Load(); # good + LoadByName(); # good + LoadById(); # good + +Subroutines beginning with C<_> are special: they are not to be used +outside the current object. There is not to be enforced by the code +itself, but by someone very big and very scary. + +For large for() loops, do not use $_, but name the variable. +Do not use $_ (or assume it) except for when it is absolutely +clear what is going on, or when it is required (such as with +map() and grep()). + + for (@list) { + print; # OK; everyone knows this one + print uc; # wrong; few people know this + print uc $_; # better + } + +Note that the special variable C<_> I<should> be used when possible. +It is a placeholder that can be passed to stat() and the file test +operators, that saves perl a trip to re-stat the file. In the +example below, using C<$file> over for each file test, instead of +C<_> for subsequent uses, is a performance hit. You should be +careful that the last-tested file is what you think it is, though. + + if (-d $file) { # $file is a directory + # ... + } elsif (-l _) { # $file is a symlink + # ... + } + +Package names begin with a capital letter in each word, followed by +lower case letters (for the most part). Multiple words should be StudlyCapped. + + RT::User # good + RT::Database::MySQL # proper name + RT::Display::Provider # good + RT::CustomField # not so good, but OK + +Plugin modules should begin with "RTx::", followed by the name +of the plugin. + +=head1 Code formatting + +Use perltidy. Anything we say here is wrong if it conflicts with what +perltidy does. Your perltidyrc should read: + +-lp -vt=2 -vtc=2 -nsfs -bar + +=head2 Indents and Blank Space + +All indents should be tabs. Set your tab stops whatever you want them +to be; I use 8 spaces per tabs. + +No space before a semicolon that closes a statement. + + foo(@bar) ; # wrong + foo(@bar); # right + +Line up corresponding items vertically. + + my $foo = 1; + my $bar = 2; + my $xyzzy = 3; + + open(FILE, $fh) or die $!; + open(FILE2, $fh2) or die $!; + + $rot13 =~ tr[abcedfghijklmnopqrstuvwxyz] + [nopqrstuvwxyzabcdefghijklm]; + + # note we use a-mn-z instead of a-z, + # for readability + $rot13 =~ tr[a-mn-z] + [n-za-m]; + +Put blank lines between groups of code that do different things. Put +blank lines after your variable declarations. Put a blank line before a +final return() statement. Put a blank line following a block (and +before, with the exception of comment lines). + +An example: + + # this is my function! + sub foo { + my $val = shift; + my $obj = new Constructor; + my($var1, $var2); + + $obj->SetFoo($val); + $var1 = $obj->Foo(); + + + return($val); + } + + print 1; + + +=head2 Parentheses + +For control structures, there is a space between the keyword and opening +parenthesis. For functions, there is not. + + for(@list) # wrong + for (@list) # right + + my ($ref) # wrong + my($ref) # right + +Be careful about list vs. scalar context with parentheses! + + my @array = ('a', 'b', 'c'); + my($first_element) = @array; # a + my($first_element) = ('a', 'b', 'c'); # a + my $element_count = @array; # 3 + my $last_element = ('a', 'b', 'c'); # c + +Always include parentheses after functions, even if there are no arguments. +There are some exceptions, such as list operators (like print) and unary +operators (like undef, delete, uc). + +There is no space inside the parentheses, unless it is needed for +readability. + + for ( map { [ $_, 1 ] } @list ) # OK + for ( @list ) # not really OK, not horrible + +On multi-line expressions, match up the closing parenthesis with either +the opening statement, or the opening parenthesis, whichever works best. +Examples: + + @list = qw( + bar + baz + ); # right + + if ($foo && $bar && $baz + && $buz && $xyzzy + ) { + print $foo; + } + +Whether or not there is space following a closing parenthesis is +dependent on what it is that follows. + + print foo(@bar), baz(@buz) if $xyzzy; + +Note also that parentheses around single-statement control expressions, +as in C<if $xyzzy>, are optional (and discouraged) C<if> it is I<absolutely> +clear -- to a programmer -- what is going on. There is absolutely no +need for parentheses around C<$xyzzy> above, so leaving them out enhances +readability. Use your best discretion. Better to include them, if +there is any question. + +The same essentially goes for perl's built-in functions, when there is +nothing confusing about what is going on (for example, there is only one +function call in the statement, or the function call is separated by a +flow control operator). User-supplied functions must always include +parentheses. + + print 1, 2, 3; # good + delete $hash{key} if isAnon($uid); # good + + +However, if there is any possible confusion at all, then include the +parentheses. Remember the words of Larry Wall in the perlstyle manpage: + + When in doubt, parenthesize. At the very least it will + let some poor schmuck bounce on the % key in vi. + + Even if you aren't in doubt, consider the mental welfare + of the person who has to maintain the code after you, and + who will probably put parens in the wrong place. + +So leave them out when it is absoutely clear to a programmer, but if +there is any question, leave them in. + + +=head2 Braces + +(This is about control braces, not hash/data structure braces.) + +There is always a space befor the opening brace. + + while (<$fh>){ # wrong + while (<$fh>) { # right + +A one-line block may be put on one line, and the semicolon may be +omitted. + + for (@list) { print } + +Otherwise, finish each statement with a semicolon, put the keyword and +opening curly on the first line, and the ending curly lined up with the +keyword at the end. + + for (@list) { + print; + smell(); + } + +Generally, we prefer "uncuddled elses": + + if ($foo) { + print; + } + else { + die; + } + +_If_ the if statement is very brief, sometimes "cuddling" the else makes code more readable. Feel free to cuddle them in that case: + + + if ($foo) { + print; + } else { + die; + } + +=head2 Operators + +Put space around most operators. The primary exception is the for +aesthetics; e.g., sometimes the space around "**" is ommitted, +and there is never a space before a ",", but always after. + + print $x , $y; # wrong + print $x, $y; # right + + $x = 2 >> 1; # good + $y = 2**2; # ok + +Note that "&&" and "||" have a higher precedence than "and" and "or". +Other than that, they are exactly the same. It is best to use the lower +precedence version for control, and the higher for testing/returning +values. Examples: + + $bool = $flag1 or $flag2; # WRONG (doesn't work) + $value = $foo || $bar; # right + open(FILE, $file) or die $!; + + $true = foo($bar) && baz($buz); + foo($bar) and baz($buz); + +Note that "and" is seldom ever used, because the statement above is +better written using "if": + + baz($buz) if foo($bar); + +Most of the time, the confusion between and/&&, or/|| can be alleviated +by using parentheses. If you want to leave off the parentheses then you +I<must> use the proper operator. But if you use parentheses -- and +normally, you should, if there is any question at all -- then it doesn't +matter which you use. Use whichever is most readable and aesthetically +pleasing to you at the time, and be consistent within your block of code. + +Break long lines AFTER operators, except for "and", "or", "&&", "||". +Try to keep the two parts to a binary operator (an operator that +has two operands) together when possible. + + print "foo" . "bar" . "baz" + . "buz"; # wrong + + print "foo" . "bar" . "baz" . + "buz"; # right + + print $foo unless $x == 3 && $y == + 4 && $z == 5; # wrong + + print $foo unless $x == 3 && $y == 4 + && $z == 5; # right + + +=head2 Other + +Put space around a complex subscript inside the brackets or braces. + + $foo{$bar{baz}{buz}}; # OK + $foo{ $bar{baz}{buz} }; # better + +In general, use single-quotes around literals, and double-quotes +when the text needs to be interpolated. + +It is OK to omit quotes around names in braces and when using +the => operator, but be careful not to use a name that doubles as +a function; in that case, quote. + + $what{'time'}{it}{is} = time(); + +When making compound statements, put the primary action first. + + open(FILE, $fh) or die $!; # right + die $! unless open(FILE, $fh); # wrong + + print "Starting\n" if $verbose; # right + $verbose && print "Starting\n"; # wrong + + +Use here-docs instead of repeated print statements. + + print <<EOT; + This is a whole bunch of text. + I like it. I don't need to worry about messing + with lots of print statements and lining them up. + EOT + +Just remember that unless you put single quotes around your here-doc +token (<<'EOT'), the text will be interpolated, so escape any "$" or "@" +as needed. + +=head1 INTERNATIONALIZATION + + +=head2 String extraction styleguide + +=over 4 + +=item Web templates + +Templates should use the /l filtering component to call the localisation +framework + +The string Foo! + +Should become <&|/l&>Foo!</&> + +All newlines should be removed from localized strings, to make it easy to +grep the codebase for strings to be localized + +The string Foo + Bar + Baz + +Should become <&|/l&>Foo Bar Baz</&> + + +Variable subsititutions should be moved to Locale::MakeText format + +The string Hello, <%$name %> + +should become <&|/l, $name &>Hello, [_1]</&> + + +Multiple variables work just like single variables + +The string You found <%$num%> tickets in queue <%$queue%> + +should become <&|/l, $num, $queue &>You found [_1] tickets in queue [_2]</&> + +When subcomponents are called in the middle of a phrase, they need to be escaped +too: + +The string <input type="submit" value="New ticket in"> <& /Elements/SelectNewTicketQueue&> + +should become <&|/l, $m->scomp('/Elements/SelectNewTicketQueue')&><input type="submit" value="New ticket in"> [_1]</&> + + + + +The string <& /Elements/TitleBoxStart, width=> "40%", titleright => "RT $RT::VERSION for $RT::rtname", title => 'Login' &> + +should become <& /Elements/TitleBoxStart, + width=> "40%", + titleright => loc("RT [_1] for [_2]",$RT::VERSION, $RT::rtname), + title => loc('Login'), + &> + + +=item Library code + + + +Within RT's core code, every module has a localization handle available through the 'loc' method: + +The code return ( $id, "Queue created" ); + +should become return ( $id, $self->loc("Queue created") ); + +When returning or localizing a single string, the "extra" set of parenthesis () should be omitted. + +The code return ("Subject changed to ". $self->Data ); + +should become return $self->loc( "Subject changed to [_1]", $self->Data ); + + +It is important not to localize the names of rights or statuses within RT's core, as there is logic that depends on them as string identifiers. The proper place to localize these values is when they're presented for display in the web or commandline interfaces. + + +=back 4 + +=head1 CODING PRCEDURE + +This is for new programs, modules, specific APIs, or anything else. + +Contact for core team is the slashcode-development mailing list. + +=over 4 + +=item Present idea to core team + +We may know of a better way to approach the problem, or know of an +existing way to deal with it, or know someone else is working on it. +This is mostly informal, but a fairly complete explanation for the need +and use of the code should be provided. + + +=item Present complete specs to core team + +The complete proposed API to the core team should be submitted for +approval and discussion. For web and command-line programs, present the +functionality and interface (op codes, command-lin switches, etc.). + +The best way to do this is to take the documentation portion of the +boilerplate and fill it in. You can make changes later if necessary, +but fill it in as much as you can. + + +=item Announce any changes to interface + +If the way it works or how it is called is going to change, notify the core +team. + + +=item Prepare for core review + +When you are done, the code will undergo a code review by a member of +the core team, or someone picked by the core team. This is not to +belittle you (that's just a nice side effect), it is to make sure that +you understand your code, that we understand your code, that it won't +break other code, that it follows the documentation and existing +proposal. It is to check for possible optimizations or better ways of +doing it. + +For members of the core team, one or more other members of the team will +perform the review. + +Note that all code is expected to follow the coding principles and style +guide contained in this document. + + +=item Finish it up + +After the code is done (possibly going through multiple code reviews), +if you do not have repository access, submit it to rt-<major-version>-bugs@fsck.com as a unified diff. From that point on, it'll be handled by someone with repository access. + +=back + + +=head1 BUG REPORTS, PATCHES + +Use rt-<major-version>-bugs@fsck.com for I<any> bug that is not +being fixed immediately. If it is not in RT, there +is a good chance it will not be dealt with. + +Send patches to rt-<major-version>-bugs@fsck.com, too. Use C<diff +-u> for patches. + + + +=head1 TO DO + +Talk about DBIx::SearchBuilder + +Talk about mason + component style + cascading style sheets + +Talk about adding a new translation + +Talk more about logging + +=head1 CHANGES + + Adapted from Slash Styleguide by jesse - 20 Dec, 2002 + + +=head1 VERSION + +0.1 diff --git a/rt/lib/RT/Template_Overlay.pm b/rt/lib/RT/Template_Overlay.pm index 0b5e67d0f..5950aa3ea 100644 --- a/rt/lib/RT/Template_Overlay.pm +++ b/rt/lib/RT/Template_Overlay.pm @@ -203,10 +203,11 @@ sub LoadQueueTemplate { my $self = shift; my %args = ( Queue => undef, - Name => undef + Name => undef, + @_ ); - return ( $self->LoadByCols( Name => $args{'Name'}, Queue => {'Queue'} ) ); + return ( $self->LoadByCols( Name => $args{'Name'}, Queue => $args{'Queue'} ) ); } @@ -318,24 +319,30 @@ sub Parse { my $parser = MIME::Parser->new(); # Setup output directory for files. from RT::EmailParser::_SetupMIMEParser - if (my $AttachmentDir = eval { File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 ) }) { - # Set up output directory for files: - $parser->output_dir("$AttachmentDir"); + if ( my $AttachmentDir = + eval { File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 ) } ) + { + + # Set up output directory for files: + $parser->output_dir("$AttachmentDir"); } else { - # On some situations TMPDIR is non-writable. sad but true. - $parser->output_to_core(1); - $parser->tmp_to_core(1); + $RT::Logger->error("Couldn't write attachments to temp dir on disk. using more memory and processor."); + # On some situations TMPDIR is non-writable. sad but true. + $parser->output_to_core(1); + $parser->tmp_to_core(1); } + #If someone includes a message, don't extract it $parser->extract_nested_messages(1); + # Set up the prefix for files with auto-generated names: $parser->output_prefix("part"); + # If content length is <= 50000 bytes, store each msg as in-core scalar; # Else, write to a disk file (the default action): $parser->output_to_core(50000); - ### Should we forgive normally-fatal errors? $parser->ignore_errors(1); $self->{'MIMEObj'} = eval { $parser->parse_data($content) }; @@ -350,7 +357,6 @@ sub Parse { $self->{'MIMEObj'}->head->unfold(); return ( 1, $self->loc("Template parsed") ); - } @@ -369,12 +375,13 @@ sub _ParseContent { @_ ); - + no warnings 'redefine'; $T::Ticket = $args{'TicketObj'}; $T::Transaction = $args{'TransactionObj'}; $T::Argument = $args{'Argument'}; $T::Requestor = eval { $T::Ticket->Requestors->UserMembersObj->First->Name }; $T::rtname = $RT::rtname; + *T::loc = sub { $T::Ticket->loc(@_) }; # We need to untaint the content of the template, since we'll be working # with it diff --git a/rt/lib/RT/Ticket_Overlay.pm b/rt/lib/RT/Ticket_Overlay.pm index c88bbc90f..981df4125 100644 --- a/rt/lib/RT/Ticket_Overlay.pm +++ b/rt/lib/RT/Ticket_Overlay.pm @@ -305,6 +305,7 @@ sub Create { my $self = shift; my %args = ( id => undef, + EffectiveId => undef, Queue => undef, Requestor => undef, Cc => undef, @@ -314,6 +315,7 @@ sub Create { Subject => '', InitialPriority => undef, FinalPriority => undef, + Priority => undef, Status => 'new', TimeWorked => "0", TimeLeft => 0, @@ -378,6 +380,11 @@ sub Create { $args{'FinalPriority'} = ( $QueueObj->FinalPriority || 0 ) unless ( defined $args{'FinalPriority'} ); + # Priority may have changed from InitialPriority, for the case + # where we're importing tickets (eg, from an older RT version.) + my $priority = $args{'Priority'} || $args{'InitialPriority'}; + + # {{{ Dates #TODO we should see what sort of due date we're getting, rather + # than assuming it's in ISO format. @@ -473,7 +480,7 @@ sub Create { next unless (defined $args{$type}); foreach my $watcher ( ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) ) { my $user = RT::User->new($RT::SystemUser); - $user->LoadOrCreateByEmail($watcher) if ($watcher !~ /^\d+$/); + $user->LoadOrCreateByEmail($watcher) if ($watcher && $watcher !~ /^\d+$/); } } @@ -485,7 +492,7 @@ sub Create { Subject => $args{'Subject'}, InitialPriority => $args{'InitialPriority'}, FinalPriority => $args{'FinalPriority'}, - Priority => $args{'InitialPriority'}, + Priority => $priority, Status => $args{'Status'}, TimeWorked => $args{'TimeWorked'}, TimeEstimated => $args{'TimeEstimated'}, @@ -515,7 +522,7 @@ sub Create { } #Set the ticket's effective ID now that we've created it. - my ( $val, $msg ) = $self->__Set( Field => 'EffectiveId', Value => $id ); + my ( $val, $msg ) = $self->__Set( Field => 'EffectiveId', Value => ($args{'EffectiveId'} || $id ) ); unless ($val) { $RT::Logger->crit("$self ->Create couldn't set EffectiveId: $msg\n"); @@ -546,6 +553,9 @@ sub Create { next unless (defined $args{$type}); foreach my $watcher ( ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) ) { + # If there is an empty entry in the list, let's get out of here. + next unless $watcher; + # we reason that all-digits number must be a principal id, not email # this is the only way to can add my $field = 'Email'; @@ -601,7 +611,7 @@ sub Create { my $cfid = $1; foreach my $value ( ref( $args{$arg} ) ? @{ $args{$arg} } : ( $args{$arg} ) ) { - next unless ($value); + next unless (length($value)); $self->_AddCustomFieldValue( Field => $cfid, Value => $value, RecordTransaction => 0 @@ -832,8 +842,8 @@ AddRequestor: jesse\@example.com EOF my $ticket = RT::Ticket->new($RT::SystemUser); -$ticket->Create(Subject => 'first', Queue => 'general'); -ok($ticket->Id, "Created the test ticket"); +my ($id,$msg) =$ticket->Create(Subject => 'first', Queue => 'general'); +ok($ticket->Id, "Created the test ticket - ".$id ." - ".$msg); $ticket->UpdateFrom822($simple_update); is($ticket->Subject, 'target', "changed the subject"); my $jesse = RT::User->new($RT::SystemUser); @@ -970,7 +980,7 @@ sub UpdateFrom822 { # If we've been given a number of delresses to del, do it. foreach my $address (@{$ticketargs{'Del'.$type}}) { - my ($id, $msg) = $self->DelWatcher( Type => $type, Email => $address); + my ($id, $msg) = $self->DeleteWatcher( Type => $type, Email => $address); push (@results, $msg) ; } @@ -2228,9 +2238,11 @@ sub Comment { # The "NotifyOtherRecipients" scripAction will look for RT--Send-Cc: and # RT-Send-Bcc: headers - $args{'MIMEObj'}->head->add( 'RT-Send-Cc', $args{'CcMessageTo'} ) + $args{'MIMEObj'}->head->add( 'RT-Send-Cc', + RT::User::CanonicalizeEmailAddress(undef, $args{'CcMessageTo'}) ) if defined $args{'CcMessageTo'}; - $args{'MIMEObj'}->head->add( 'RT-Send-Bcc', $args{'BccMessageTo'} ) + $args{'MIMEObj'}->head->add( 'RT-Send-Bcc', + RT::User::CanonicalizeEmailAddress(undef, $args{'BccMessageTo'}) ) if defined $args{'BccMessageTo'}; #Record the correspondence (write the transaction) @@ -2296,9 +2308,11 @@ sub Correspond { # The "NotifyOtherRecipients" scripAction will look for RT-Send-Cc: and RT-Send-Bcc: # headers - $args{'MIMEObj'}->head->add( 'RT-Send-Cc', $args{'CcMessageTo'} ) + $args{'MIMEObj'}->head->add( 'RT-Send-Cc', + RT::User::CanonicalizeEmailAddress(undef, $args{'CcMessageTo'}) ) if defined $args{'CcMessageTo'}; - $args{'MIMEObj'}->head->add( 'RT-Send-Bcc', $args{'BccMessageTo'} ) + $args{'MIMEObj'}->head->add( 'RT-Send-Bcc', + RT::User::CanonicalizeEmailAddress(undef, $args{'BccMessageTo'}) ) if defined $args{'BccMessageTo'}; #Record the correspondence (write the transaction) @@ -2894,9 +2908,6 @@ sub MergeInto { } - #make a new link: this ticket is merged into that other ticket. - $self->AddLink( Type => 'MergedInto', Target => $NewTicket->Id()); - #add all of this ticket's watchers to that ticket. my $requestors = $self->Requestors->MembersObj; while (my $watcher = $requestors->Next) { @@ -2936,6 +2947,9 @@ sub MergeInto { ); } + #make a new link: this ticket is merged into that other ticket. + $self->AddLink( Type => 'MergedInto', Target => $NewTicket->Id()); + $NewTicket->_SetLastUpdated; return ( 1, $self->loc("Merge Successful") ); @@ -3266,8 +3280,14 @@ sub SetStatus { } #Check ACL - unless ( $self->CurrentUserHasRight('ModifyTicket') ) { - return ( 0, $self->loc('Permission Denied') ); + if ( $args{Status} eq 'deleted') { + unless ($self->CurrentUserHasRight('DeleteTicket')) { + return ( 0, $self->loc('Permission Denied') ); + } + } else { + unless ($self->CurrentUserHasRight('ModifyTicket')) { + return ( 0, $self->loc('Permission Denied') ); + } } if (!$args{Force} && ($args{'Status'} eq 'resolved') && $self->HasUnresolvedDependencies) { @@ -3440,6 +3460,7 @@ sub CustomFieldValues { my $cf_values = RT::TicketCustomFieldValues->new( $self->CurrentUser ); $cf_values->LimitToCustomField($cf->id); $cf_values->LimitToTicket($self->Id()); + $cf_values->OrderBy( FIELD => 'id' ); # @values is a CustomFieldValues object; return ($cf_values); @@ -3451,7 +3472,7 @@ sub CustomFieldValues { =item AddCustomFieldValue { Field => FIELD, Value => VALUE } -VALUE can either be a CustomFieldValue object or a string. +VALUE should be a string. FIELD can be a CustomField object OR a CustomField ID. @@ -3798,11 +3819,45 @@ sub _NewTransaction { if ( defined $args{'TimeTaken'} ) { $self->_UpdateTimeTaken( $args{'TimeTaken'} ); } + if ( $RT::UseTransactionBatch and $transaction ) { + push @{$self->{_TransactionBatch}}, $trans; + } return ( $transaction, $msg, $trans ); } # }}} +=head2 TransactionBatch + + Returns an array reference of all transactions created on this ticket during + this ticket object's lifetime, or undef if there were none. + + Only works when the $RT::UseTransactionBatch config variable is set to true. + +=cut + +sub TransactionBatch { + my $self = shift; + return $self->{_TransactionBatch}; +} + +sub DESTROY { + my $self = shift; + + # The following line eliminates reentrancy. + # It protects against the fact that perl doesn't deal gracefully + # when an object's refcount is changed in its destructor. + return if $self->{_Destroyed}++; + + my $batch = $self->TransactionBatch or return; + require RT::Scrips; + RT::Scrips->new($RT::SystemUser)->Apply( + Stage => 'TransactionBatch', + TicketObj => $self, + TransactionObj => $batch->[0], + ); +} + # }}} # {{{ PRIVATE UTILITY METHODS. Mostly needed so Ticket can be a DBIx::Record diff --git a/rt/lib/RT/Tickets_Overlay.pm b/rt/lib/RT/Tickets_Overlay.pm index d8a1ac803..55777b0fb 100644 --- a/rt/lib/RT/Tickets_Overlay.pm +++ b/rt/lib/RT/Tickets_Overlay.pm @@ -84,7 +84,7 @@ my %FIELDS = RefersTo => ['LINK' => To => 'RefersTo',], HasMember => ['LINK' => From => 'MemberOf',], DependentOn => ['LINK' => From => 'DependsOn',], - ReferredTo => ['LINK' => From => 'RefersTo',], + ReferredToBy => ['LINK' => From => 'RefersTo',], # HasDepender => ['LINK',], # RelatedTo => ['LINK',], Told => ['DATE' => 'Told',], @@ -122,14 +122,23 @@ my %dispatch = LINKFIELD => \&_LinkFieldLimit, CUSTOMFIELD => \&_CustomFieldLimit, ); +my %can_bundle = + ( WATCHERFIELD => "yeps", + ); # Default EntryAggregator per type +# if you specify OP, you must specify all valid OPs my %DefaultEA = ( INT => 'AND', ENUM => { '=' => 'OR', '!='=> 'AND' }, - DATE => 'AND', + DATE => { '=' => 'OR', + '>='=> 'AND', + '<='=> 'AND', + '>' => 'AND', + '<' => 'AND' + }, STRING => { '=' => 'OR', '!='=> 'AND', 'LIKE'=> 'AND', @@ -137,6 +146,7 @@ my %DefaultEA = ( }, TRANSFIELD => 'AND', TRANSDATE => 'AND', + LINK => 'OR', LINKFIELD => 'AND', TARGET => 'AND', BASE => 'AND', @@ -154,6 +164,7 @@ my %DefaultEA = ( # into Tickets_Overlay_SQL. sub FIELDS { return \%FIELDS } sub dispatch { return \%dispatch } +sub can_bundle { return \%can_bundle } # Bring in the clowns. require RT::Tickets_Overlay_SQL; @@ -345,7 +356,7 @@ sub _DateLimit { my ($sb,$field,$op,$value,@rest) = @_; die "Invalid Date Op: $op" - unless $op =~ /^(=|!=|>|<|>=|<=)$/; + unless $op =~ /^(=|>|<|>=|<=)$/; my $meta = $FIELDS{$field}; die "Incorrect Meta Data for $field" @@ -354,18 +365,52 @@ sub _DateLimit { require Time::ParseDate; use POSIX 'strftime'; + # FIXME: Replace me with RT::Date( Type => 'unknown' ...) my $time = Time::ParseDate::parsedate( $value, UK => $RT::DateDayBeforeMonth, PREFER_PAST => $RT::AmbiguousDayInPast, - PREFER_FUTURE => !($RT::AmbiguousDayInPast)); - $value = strftime("%Y-%m-%d %H:%M",localtime($time)); + PREFER_FUTURE => !($RT::AmbiguousDayInPast), + FUZZY => 1 + ); - $sb->_SQLLimit( - FIELD => $meta->[1], - OPERATOR => $op, - VALUE => $value, - @rest, - ); + if ($op eq "=") { + # if we're specifying =, that means we want everything on a + # particular single day. in the database, we need to check for > + # and < the edges of that day. + + my $daystart = strftime("%Y-%m-%d %H:%M", + gmtime($time - ( $time % 86400 ))); + my $dayend = strftime("%Y-%m-%d %H:%M", + gmtime($time + ( 86399 - $time % 86400 ))); + + $sb-> _OpenParen; + + $sb->_SQLLimit( + FIELD => $meta->[1], + OPERATOR => ">=", + VALUE => $daystart, + @rest, + ); + + $sb->_SQLLimit( + FIELD => $meta->[1], + OPERATOR => "<=", + VALUE => $dayend, + @rest, + ENTRYAGGREGATOR => 'AND', + ); + + $sb-> _CloseParen; + + } else { + $value = strftime("%Y-%m-%d %H:%M", gmtime($time)); + $sb->_SQLLimit( + FIELD => $meta->[1], + OPERATOR => $op, + VALUE => $value, + @rest, + ); + } } =head2 _StringLimit @@ -425,8 +470,8 @@ sub _TransDateLimit { ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'Ticket'); my $d = new RT::Date( $sb->CurrentUser ); - $d->Set($value); - $value = $d->ISO; + $d->Set( Format => 'ISO', Value => $value); + $value = $d->ISO; #Search for the right field $sb->_SQLLimit(ALIAS => $sb->{_sql_trattachalias}, @@ -528,9 +573,7 @@ sub _WatcherLimit { $self->_OpenParen; my $groups = $self->NewAlias('Groups'); - my $group_princs = $self->NewAlias('Principals'); my $groupmembers = $self->NewAlias('CachedGroupMembers'); - my $member_princs = $self->NewAlias('Principals'); my $users = $self->NewAlias('Users'); @@ -542,14 +585,29 @@ sub _WatcherLimit { # $aggregator = 'AND'; # } - - $self->_SQLLimit(ALIAS => $users, - FIELD => $rest{SUBKEY} || 'EmailAddress', - VALUE => $value, - OPERATOR => $op, - CASESENSITIVE => 0, - @rest, - ); + if (ref $field) { # gross hack + my @bundle = @$field; + $self->_OpenParen; + for my $chunk (@bundle) { + ($field,$op,$value,@rest) = @$chunk; + $self->_SQLLimit(ALIAS => $users, + FIELD => $rest{SUBKEY} || 'EmailAddress', + VALUE => $value, + OPERATOR => $op, + CASESENSITIVE => 0, + @rest, + ); + } + $self->_CloseParen; + } else { + $self->_SQLLimit(ALIAS => $users, + FIELD => $rest{SUBKEY} || 'EmailAddress', + VALUE => $value, + OPERATOR => $op, + CASESENSITIVE => 0, + @rest, + ); + } # {{{ Tie to groups for tickets we care about $self->_SQLLimit(ALIAS => $groups, @@ -573,17 +631,9 @@ sub _WatcherLimit { } $self->Join (ALIAS1 => $groups, FIELD1 => 'id', - ALIAS2 => $group_princs, FIELD2 => 'ObjectId'); - $self->_SQLLimit(ALIAS => $group_princs, - FIELD => 'PrincipalType', - VALUE => 'Group', - ENTRYAGGREGATOR => 'AND'); - $self->Join( ALIAS1 => $group_princs, FIELD1 => 'id', ALIAS2 => $groupmembers, FIELD2 => 'GroupId'); $self->Join( ALIAS1 => $groupmembers, FIELD1 => 'MemberId', - ALIAS2 => $member_princs, FIELD2 => 'id'); - $self->Join (ALIAS1 => $member_princs, FIELD1 => 'ObjectId', ALIAS2 => $users, FIELD2 => 'id'); $self->_CloseParen; @@ -679,6 +729,7 @@ sub _CustomFieldLimit { $CF->LimitToQueue( $q->Id ); $queue = $q->Id; } else { + $field = $1 if $field =~ /^{(.+)}$/; # trim { } $CF->LimitToGlobal; } $CF->FindAllRows; @@ -700,11 +751,19 @@ sub _CustomFieldLimit { my $null_columns_ok; - my $TicketCFs = $self->Join( TYPE => 'left', - ALIAS1 => 'main', - FIELD1 => 'id', - TABLE2 => 'TicketCustomFieldValues', - FIELD2 => 'Ticket' ); + + my $TicketCFs; + # Perform one Join per CustomField + if ($self->{_sql_keywordalias}{$cfid}) { + $TicketCFs = $self->{_sql_keywordalias}{$cfid}; + } else { + $TicketCFs = $self->{_sql_keywordalias}{$cfid} = + $self->Join( TYPE => 'left', + ALIAS1 => 'main', + FIELD1 => 'id', + TABLE2 => 'TicketCustomFieldValues', + FIELD2 => 'Ticket' ); + } $self->_OpenParen; @@ -1373,11 +1432,18 @@ sub LimitLinkedFrom { TYPE => undef, @_); + # translate RT2 From/To naming to RT3 TicketSQL naming + my %fromToMap = qw(DependsOn DependentOn + MemberOf HasMember + RefersTo ReferredToBy); + + my $type = $args{'TYPE'}; + $type = $fromToMap{$type} if exists($fromToMap{$type}); $self->Limit( FIELD => 'LinkedTo', TARGET => undef, BASE => ($args{'BASE'} || $args{'TICKET'}), - TYPE => $args{'TYPE'}, + TYPE => $type, DESCRIPTION => $self->loc( "Tickets [_1] [_2]", $self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}) ), @@ -1581,11 +1647,12 @@ Takes a paramhash of key/value pairs with the following keys: =over 4 -=item KEYWORDSELECT - KeywordSelect id +=item CUSTOMFIELD - CustomField name or id. If a name is passed, an additional +parameter QUEUE may also be passed to distinguish the custom field. -=item OPERATOR - (for KEYWORD only - KEYWORDSELECT operator is always `=') +=item OPERATOR - The usual Limit operators -=item KEYWORD - Keyword id +=item VALUE - The value to compare against =back @@ -1603,7 +1670,13 @@ sub LimitCustomField { use RT::CustomFields; my $CF = RT::CustomField->new( $self->CurrentUser ); - $CF->Load( $args{CUSTOMFIELD} ); + if ( $args{CUSTOMFIELD} =~ /^\d+$/) { + $CF->Load( $args{CUSTOMFIELD} ); + } + else { + $CF->LoadByNameAndQueue( Name => $args{CUSTOMFIELD}, Queue => $args{QUEUE} ); + $args{CUSTOMFIELD} = $CF->Id; + } #If we are looking to compare with a null value. if ( $args{'OPERATOR'} =~ /^is$/i ) { @@ -1618,10 +1691,6 @@ sub LimitCustomField { $args{'DESCRIPTION'} ||= $self->loc("Custom field [_1] [_2] [_3]", $CF->Name , $args{OPERATOR} , $args{VALUE}); } -# my $index = $self->_NextIndex; -# %{ $self->{'TicketRestrictions'}{$index} } = %args; - - my $q = ""; if ($CF->Queue) { my $qo = new RT::Queue( $self->CurrentUser ); @@ -1629,6 +1698,10 @@ sub LimitCustomField { $q = $qo->Name; } + my @rest; + @rest = ( ENTRYAGGREGATOR => 'AND' ) + if ($CF->Type eq 'SelectMultiple'); + $self->Limit( VALUE => $args{VALUE}, FIELD => "CF.".( $q ? $q . ".{" . $CF->Name . "}" @@ -1636,11 +1709,11 @@ sub LimitCustomField { ), OPERATOR => $args{OPERATOR}, CUSTOMFIELD => 1, + @rest, ); $self->{'RecalcTicketLimits'} = 1; - # return ($index); } # }}} @@ -1924,12 +1997,19 @@ sub _RestrictionsToClauses { # defined $restriction->{'TARGET'} ? # $restriction->{TARGET} ) - my $ea = $DefaultEA{$type}; + my $ea = $restriction->{ENTRYAGGREGATOR} || $DefaultEA{$type} || "AND"; if ( ref $ea ) { die "Invalid operator $op for $field ($type)" unless exists $ea->{$op}; $ea = $ea->{$op}; } + + # Each CustomField should be put into a different Clause so they + # are ANDed together. + if ($restriction->{CUSTOMFIELD}) { + $realfield = $field; + } + exists $clause{$realfield} or $clause{$realfield} = []; # Escape Quotes $field =~ s!(['"])!\\$1!g; @@ -1963,6 +2043,11 @@ sub _ProcessRestrictions { #a new search delete $self->{'TicketAliases'}; delete $self->{'items_array'}; + delete $self->{'item_map'}; + delete $self->{'raw_rows'}; + delete $self->{'rows'}; + delete $self->{'count_all'}; + my $sql = $self->{_sql_query}; # Violating the _SQL namespace if (!$sql||$self->{'RecalcTicketLimits'}) { # "Restrictions to Clauses Branch\n"; @@ -1995,12 +2080,12 @@ sub _BuildItemMap { delete $self->{'item_map'}; if ($items->[0]) { - $self->{'item_map'}->{'first'} = $items->[0]->Id; + $self->{'item_map'}->{'first'} = $items->[0]->EffectiveId; while (my $item = shift @$items ) { - my $id = $item->Id; + my $id = $item->EffectiveId; $self->{'item_map'}->{$id}->{'defined'} = 1; $self->{'item_map'}->{$id}->{prev} = $prev; - $self->{'item_map'}->{$id}->{next} = $items->[0]->Id if ($items->[0]); + $self->{'item_map'}->{$id}->{next} = $items->[0]->EffectiveId if ($items->[0]); $prev = $id; } $self->{'item_map'}->{'last'} = $prev; diff --git a/rt/lib/RT/Tickets_Overlay_SQL.pm b/rt/lib/RT/Tickets_Overlay_SQL.pm index d78a56db3..629e6da2d 100644 --- a/rt/lib/RT/Tickets_Overlay_SQL.pm +++ b/rt/lib/RT/Tickets_Overlay_SQL.pm @@ -29,6 +29,10 @@ use warnings; my %FIELDS = %{FIELDS()}; my %dispatch = %{dispatch()}; +my %can_bundle = %{can_bundle()}; + +# Lower Case version of FIELDS, for case insensitivity +my %lcfields = map { ( lc($_) => $_ ) } (keys %FIELDS); sub _InitSQL { my $self = shift; @@ -119,20 +123,57 @@ my $re_keyword = qr[$RE{delimited}{-delim=>qq{\'\"}}|(?:\{|\}|\w|\.)+]; my $re_op = qr[=|!=|>=|<=|>|<|(?i:IS NOT)|(?i:IS)|(?i:NOT LIKE)|(?i:LIKE)]; # long to short my $re_paren = qr'\(|\)'; +sub _close_bundle +{ + my ($self, @bundle) = @_; + return unless @bundle; + if (@bundle == 1) { + $bundle[0]->{dispatch}->( + $self, + $bundle[0]->{key}, + $bundle[0]->{op}, + $bundle[0]->{val}, + SUBCLAUSE => "", + ENTRYAGGREGATOR => $bundle[0]->{ea}, + SUBKEY => $bundle[0]->{subkey}, + ); + } else { + my @args; + for my $chunk (@bundle) { + push @args, [ + $chunk->{key}, + $chunk->{op}, + $chunk->{val}, + SUBCLAUSE => "", + ENTRYAGGREGATOR => $chunk->{ea}, + SUBKEY => $chunk->{subkey}, + ]; + } + $bundle[0]->{dispatch}->( + $self, \@args, + ); + } +} + sub _parser { my ($self,$string) = @_; my $want = KEYWORD | PAREN; my $last = undef; my $depth = 0; + my @bundle; my ($ea,$key,$op,$value) = ("","","",""); + # order of matches in the RE is important.. op should come early, + # because it has spaces in it. otherwise "NOT LIKE" might be parsed + # as a keyword or value. + while ($string =~ /( $re_aggreg + |$re_op |$re_keyword |$re_value - |$re_op |$re_paren )/igx ) { my $val = $1; @@ -156,10 +197,12 @@ sub _parser { # Parens are highest priority if ($current & PAREN) { if ($val eq "(") { + $self->_close_bundle(@bundle); @bundle = (); $depth++; $self->_OpenParen; } else { + $self->_close_bundle(@bundle); @bundle = (); $depth--; $self->_CloseParen; } @@ -204,10 +247,9 @@ sub _parser { } my $class; - my ($stdkey) = grep { /^$key$/i } (keys %FIELDS); - if ($stdkey && exists $FIELDS{$stdkey}) { + if (exists $lcfields{lc $key}) { + $key = $lcfields{lc $key}; $class = $FIELDS{$key}->[0]; - $key = $stdkey; } # no longer have a default, since CF's are now a real class, not fallthrough # fixme: "default class" is not Generic. @@ -219,20 +261,37 @@ sub _parser { die "No such dispatch method: $class" unless exists $dispatch{$class}; my $sub = $dispatch{$class} || die;; - $sub->( - $self, - $key, - $op, - $val, - SUBCLAUSE => "", # don't need anymore - ENTRYAGGREGATOR => $ea || "", - SUBKEY => $subkey, - ); + if ($can_bundle{$class} && + (!@bundle || + ($bundle[-1]->{dispatch} == $sub && + $bundle[-1]->{key} eq $key && + $bundle[-1]->{subkey} eq $subkey))) + { + push @bundle, { + dispatch => $sub, + key => $key, + op => $op, + val => $val, + ea => $ea || "", + subkey => $subkey, + }; + } else { + $self->_close_bundle(@bundle); @bundle = (); + $sub->( + $self, + $key, + $op, + $val, + SUBCLAUSE => "", # don't need anymore + ENTRYAGGREGATOR => $ea || "", + SUBKEY => $subkey, + ); + } $self->{_sql_looking_at}{lc $key} = 1; - + ($ea,$key,$op,$value) = ("","","",""); - + $want = PAREN | AGGREG; } else { die "I'm lost"; @@ -241,6 +300,8 @@ sub _parser { $last = $current; } # while + $self->_close_bundle(@bundle); @bundle = (); + die "Incomplete query" unless (($want | PAREN) || ($want | KEYWORD)); @@ -330,6 +391,10 @@ sub FromSQL { VALUE => 'ticket'); } + # We never ever want to show deleted tickets + $self->SUPER::Limit(FIELD => 'Status' , OPERATOR => '!=', VALUE => 'deleted'); + + # set SB's dirty flag $self->{'must_redo_search'} = 1; $self->{'RecalcTicketLimits'} = 0; diff --git a/rt/lib/RT/Transaction_Overlay.pm b/rt/lib/RT/Transaction_Overlay.pm index 54bb326a9..9c9a2fd14 100644 --- a/rt/lib/RT/Transaction_Overlay.pm +++ b/rt/lib/RT/Transaction_Overlay.pm @@ -51,6 +51,8 @@ ok(require RT::Transaction); use strict; no warnings qw(redefine); +use vars qw( %_BriefDescriptions ); + use RT::Attachments; # {{{ sub Create @@ -112,66 +114,13 @@ sub Create { #Provide a way to turn off scrips if we need to if ( $args{'ActivateScrips'} ) { - - #We're really going to need a non-acled ticket for the scrips to work - my $TicketAsSystem = RT::Ticket->new($RT::SystemUser); - $TicketAsSystem->Load( $args{'Ticket'} ) - || $RT::Logger->err("$self couldn't load ticket $args{'Ticket'}\n"); - - my $TransAsSystem = RT::Transaction->new($RT::SystemUser); - $TransAsSystem->Load( $self->id ) - || $RT::Logger->err( - "$self couldn't load a copy of itself as superuser\n"); - # {{{ Deal with Scrips - - use RT::Scrips; - my $PossibleScrips = RT::Scrips->new($RT::SystemUser); - - $PossibleScrips->LimitToQueue( $TicketAsSystem->QueueObj->Id ) - ; #Limit it to $Ticket->QueueObj->Id - $PossibleScrips->LimitToGlobal() - unless $TicketAsSystem->QueueObj->Disabled; # or to "global" - - - $PossibleScrips->Limit(FIELD => "Stage", VALUE => "TransactionCreate"); - - - my $ConditionsAlias = $PossibleScrips->NewAlias('ScripConditions'); - - $PossibleScrips->Join( - ALIAS1 => 'main', - FIELD1 => 'ScripCondition', - ALIAS2 => $ConditionsAlias, - FIELD2 => 'id' + require RT::Scrips; + RT::Scrips->new($RT::SystemUser)->Apply( + Stage => 'TransactionCreate', + Type => $args{'Type'}, + Ticket => $args{'Ticket'}, + Transaction => $self->id, ); - - #We only want things where the scrip applies to this sort of transaction - $PossibleScrips->Limit( - ALIAS => $ConditionsAlias, - FIELD => 'ApplicableTransTypes', - OPERATOR => 'LIKE', - VALUE => $args{'Type'}, - ENTRYAGGREGATOR => 'OR', - ); - - # Or where the scrip applies to any transaction - $PossibleScrips->Limit( - ALIAS => $ConditionsAlias, - FIELD => 'ApplicableTransTypes', - OPERATOR => 'LIKE', - VALUE => "Any", - ENTRYAGGREGATOR => 'OR', - ); - - #Iterate through each script and check it's applicability. - - while ( my $Scrip = $PossibleScrips->Next() ) { - $Scrip->Apply (TicketObj => $TicketAsSystem, - TransactionObj => $TransAsSystem); - } - - # }}} - } return ( $id, $self->loc("Transaction Created") ); @@ -535,16 +484,24 @@ sub BriefDescription { return ( $self->loc( "[_1] changed from [_2] to [_3]", $self->Field , ( $self->OldValue || $no_value ) , $self->NewValue )); } - if ( $type eq 'Correspond' ) { - return $self->loc("Correspondence added"); - } - - elsif ( $type eq 'Comment' ) { - return $self->loc("Comments added"); + if (my $code = $_BriefDescriptions{$type}) { + return $code->($self); } - elsif ( $type eq 'CustomField' ) { + return $self->loc( "Default: [_1]/[_2] changed from [_3] to [_4]", $type, $self->Field, $self->OldValue, $self->NewValue ); +} +%_BriefDescriptions = ( + Correspond => sub { + my $self = shift; + return $self->loc("Correspondence added"); + }, + Comment => sub { + my $self = shift; + return $self->loc("Comments added"); + }, + CustomField => sub { + my $self = shift; my $field = $self->loc('CustomField'); if ( $self->Field ) { @@ -563,110 +520,127 @@ sub BriefDescription { else { return $self->loc("[_1] [_2] changed to [_3]", $field, $self->OldValue, $self->NewValue ); } - } - - elsif ( $type eq 'Untake' ) { + }, + Untake => sub { + my $self = shift; return $self->loc("Untaken"); - } - - elsif ( $type eq "Take" ) { + }, + Take => sub { + my $self = shift; return $self->loc("Taken"); - } - - elsif ( $type eq "Force" ) { + }, + Force => sub { + my $self = shift; my $Old = RT::User->new( $self->CurrentUser ); $Old->Load( $self->OldValue ); my $New = RT::User->new( $self->CurrentUser ); $New->Load( $self->NewValue ); return $self->loc("Owner forcibly changed from [_1] to [_2]" , $Old->Name , $New->Name); - } - elsif ( $type eq "Steal" ) { + }, + Steal => sub { + my $self = shift; my $Old = RT::User->new( $self->CurrentUser ); $Old->Load( $self->OldValue ); return $self->loc("Stolen from [_1] ", $Old->Name); - } - - elsif ( $type eq "Give" ) { + }, + Give => sub { + my $self = shift; my $New = RT::User->new( $self->CurrentUser ); $New->Load( $self->NewValue ); return $self->loc( "Given to [_1]", $New->Name ); - } - - elsif ( $type eq 'AddWatcher' ) { + }, + AddWatcher => sub { + my $self = shift; my $principal = RT::Principal->new($self->CurrentUser); $principal->Load($self->NewValue); return $self->loc( "[_1] [_2] added", $self->Field, $principal->Object->Name); - } - - elsif ( $type eq 'DelWatcher' ) { + }, + DelWatcher => sub { + my $self = shift; my $principal = RT::Principal->new($self->CurrentUser); $principal->Load($self->OldValue); return $self->loc( "[_1] [_2] deleted", $self->Field, $principal->Object->Name); - } - - elsif ( $type eq 'Subject' ) { + }, + Subject => sub { + my $self = shift; return $self->loc( "Subject changed to [_1]", $self->Data ); - } + }, + AddLink => sub { + my $self = shift; + my $value; + if ( $self->NewValue ) { + my $URI = RT::URI->new( $self->CurrentUser ); + $URI->FromURI( $self->NewValue ); + if ( $URI->Resolver ) { + $value = $URI->Resolver->AsString; + } + else { + $value = $self->NewValue; + } + if ( $self->Field eq 'DependsOn' ) { + return $self->loc( "Dependency on [_1] added", $value ); + } + elsif ( $self->Field eq 'DependedOnBy' ) { + return $self->loc( "Dependency by [_1] added", $value ); - elsif ( $type eq 'AddLink' ) { + } + elsif ( $self->Field eq 'RefersTo' ) { + return $self->loc( "Reference to [_1] added", $value ); + } + elsif ( $self->Field eq 'ReferredToBy' ) { + return $self->loc( "Reference by [_1] added", $value ); + } + elsif ( $self->Field eq 'MemberOf' ) { + return $self->loc( "Membership in [_1] added", $value ); + } + elsif ( $self->Field eq 'HasMember' ) { + return $self->loc( "Member [_1] added", $value ); + } + } + else { + return ( $self->Data ); + } + }, + DeleteLink => sub { + my $self = shift; my $value; - if ($self->NewValue) { - my $URI = RT::URI->new($self->CurrentUser); - $URI->FromURI($self->NewValue); - if ($URI->Resolver) { - $value = $URI->Resolver->AsString; - } else { - $value = $self->NewValue; - } - } - if ($self->Field eq 'DependsOn') { - return $self->loc("Dependency on [_1] added",$value); - } elsif ($self->Field eq 'DependedOnBy') { - return $self->loc("Dependency by [_1] added",$value); - - } elsif ($self->Field eq 'RefersTo') { - return $self->loc("Reference to [_1] added",$value); - } elsif ($self->Field eq 'ReferredToBy') { - return $self->loc("Reference by [_1] added",$value); - } elsif ($self->Field eq 'MemberOf') { - return $self->loc("Membership in [_1] added",$value); - } elsif ($self->Field eq 'HasMember') { - return $self->loc("Member [_1] added",$value); - } else { - return ( $self->Data ); - } - } - elsif ( $type eq 'DeleteLink' ) { - my $value; - if ($self->OldValue) { - my $URI = RT::URI->new($self->CurrentUser); - $URI->FromURI($self->OldValue); - if ($URI->Resolver) { - $value = $URI->Resolver->AsString; - } else { - $value = $self->OldValue; - } - } - - if ($self->Field eq 'DependsOn') { - return $self->loc("Dependency on [_1] deleted",$value); - } elsif ($self->Field eq 'DependedOnBy') { - return $self->loc("Dependency by [_1] deleted",$value); - - } elsif ($self->Field eq 'RefersTo') { - return $self->loc("Reference to [_1] deleted",$value); - } elsif ($self->Field eq 'ReferredToBy') { - return $self->loc("Reference by [_1] deleted",$value); - } elsif ($self->Field eq 'MemberOf') { - return $self->loc("Membership in [_1] deleted",$value); - } elsif ($self->Field eq 'HasMember') { - return $self->loc("Member [_1] deleted",$value); - } else { - return ( $self->Data ); - } - } - elsif ( $type eq 'Set' ) { + if ( $self->OldValue ) { + my $URI = RT::URI->new( $self->CurrentUser ); + $URI->FromURI( $self->OldValue ); + if ( $URI->Resolver ) { + $value = $URI->Resolver->AsString; + } + else { + $value = $self->OldValue; + } + + if ( $self->Field eq 'DependsOn' ) { + return $self->loc( "Dependency on [_1] deleted", $value ); + } + elsif ( $self->Field eq 'DependedOnBy' ) { + return $self->loc( "Dependency by [_1] deleted", $value ); + + } + elsif ( $self->Field eq 'RefersTo' ) { + return $self->loc( "Reference to [_1] deleted", $value ); + } + elsif ( $self->Field eq 'ReferredToBy' ) { + return $self->loc( "Reference by [_1] deleted", $value ); + } + elsif ( $self->Field eq 'MemberOf' ) { + return $self->loc( "Membership in [_1] deleted", $value ); + } + elsif ( $self->Field eq 'HasMember' ) { + return $self->loc( "Member [_1] deleted", $value ); + } + } + else { + return ( $self->Data ); + } + }, + Set => sub { + my $self = shift; if ( $self->Field eq 'Queue' ) { my $q1 = new RT::Queue( $self->CurrentUser ); $q1->Load( $self->OldValue ); @@ -676,25 +650,22 @@ sub BriefDescription { } # Write the date/time change at local time: - elsif ($self->Field =~ /Due|Starts|Started|Told/) { - my $t1 = new RT::Date($self->CurrentUser); - $t1->Set(Format => 'ISO', Value => $self->NewValue); - my $t2 = new RT::Date($self->CurrentUser); - $t2->Set(Format => 'ISO', Value => $self->OldValue); - return $self->loc( "[_1] changed from [_2] to [_3]", $self->Field, $t2->AsString, $t1->AsString ); - } + elsif ($self->Field =~ /Due|Starts|Started|Told/) { + my $t1 = new RT::Date($self->CurrentUser); + $t1->Set(Format => 'ISO', Value => $self->NewValue); + my $t2 = new RT::Date($self->CurrentUser); + $t2->Set(Format => 'ISO', Value => $self->OldValue); + return $self->loc( "[_1] changed from [_2] to [_3]", $self->Field, $t2->AsString, $t1->AsString ); + } else { return $self->loc( "[_1] changed from [_2] to [_3]", $self->Field, $self->OldValue, $self->NewValue ); } - } - elsif ( $type eq 'PurgeTransaction' ) { + }, + PurgeTransaction => sub { + my $self = shift; return $self->loc("Transaction [_1] purged", $self->Data); - } - else { - return $self->loc( "Default: [_1]/[_2] changed from [_3] to [_4]", $type, $self->Field, $self->OldValue, $self->NewValue ); - - } -} + }, +); # }}} @@ -814,4 +785,12 @@ sub CurrentUserHasRight { # }}} +# Transactions don't change. by adding this cache congif directiove, we don't lose pathalogically on long tickets. +sub _CacheConfig { + { + 'cache_p' => 1, + 'fast_update_p' => 1, + 'cache_for_sec' => 180, + } +} 1; diff --git a/rt/lib/RT/URI.pm b/rt/lib/RT/URI.pm index 7acc1dc98..337a356aa 100644 --- a/rt/lib/RT/URI.pm +++ b/rt/lib/RT/URI.pm @@ -91,8 +91,10 @@ sub FromObject { =head2 FromURI <URI> -Returns a local object id for this content. You are expected to know what sort of object this is the Id -of +Returns a local object id for this content. You are expected to know +what sort of object this is the Id of + +Returns true if everything is ok, otherwise false =cut @@ -119,9 +121,12 @@ sub FromURI { unless ($self->Resolver->ParseURI($uri)) { $RT::Logger->warning("Resolver ".ref($self->Resolver)." could not parse $uri"); + $self->{resolver} = undef; # clear resolver return (undef); } +return(1); + } # }}} diff --git a/rt/lib/RT/URI/fsck_com_rt.pm b/rt/lib/RT/URI/fsck_com_rt.pm index 36e8f82fd..4035776ef 100644 --- a/rt/lib/RT/URI/fsck_com_rt.pm +++ b/rt/lib/RT/URI/fsck_com_rt.pm @@ -133,7 +133,7 @@ sub ParseURI { if ( $self->IsLocal) { my $local_uri_prefix = $self->LocalURIPrefix; - if ($self->{'uri'} =~ /^$local_uri_prefix(\d+)$/) { + if ($self->{'uri'} =~ /^$local_uri_prefix(\d+)$/i) { my $id = $1; @@ -170,7 +170,7 @@ Returns undef otherwise. sub IsLocal { my $self = shift; my $local_uri_prefix = $self->LocalURIPrefix; - if ($self->{'uri'} =~ /^$local_uri_prefix/) { + if ($self->{'uri'} =~ /^$local_uri_prefix/i) { return 1; } else { @@ -214,7 +214,7 @@ Otherwise, return its URI sub HREF { my $self = shift; - if ($self->IsLocal) { + if ($self->IsLocal && $self->Object) { return ( $RT::WebURL . "Ticket/Display.html?id=".$self->Object->Id); } else { @@ -230,12 +230,11 @@ Returns either a localized string 'ticket #23' or the full URI if the object is sub AsString { my $self = shift; - if ($self->IsLocal) { - return $self->loc("ticket #[_1]", $self->Object->Id); - + if ($self->IsLocal && $self->Object) { + return $self->loc("ticket #[_1]", $self->Object->Id); } else { - return $self->Object->URI; + return $self->URI; } } diff --git a/rt/lib/RT/User_Overlay.pm b/rt/lib/RT/User_Overlay.pm index e828ebd71..ba322cd4b 100644 --- a/rt/lib/RT/User_Overlay.pm +++ b/rt/lib/RT/User_Overlay.pm @@ -203,14 +203,16 @@ sub Create { @_ # get the real argumentlist ); - - $args{'EmailAddress'} = $self->CanonicalizeEmailAddress($args{'EmailAddress'}); - #Check the ACL unless ( $self->CurrentUser->HasRight(Right => 'AdminUsers', Object => $RT::System) ) { return ( 0, $self->loc('No permission to create users') ); } + $args{'EmailAddress'} = $self->CanonicalizeEmailAddress($args{'EmailAddress'}); + # if the user doesn't have a name defined, set it to the email address + $args{'Name'} = $args{'EmailAddress'} unless ($args{'Name'}); + + # Privileged is no longer a column in users my $privileged = $args{'Privileged'}; @@ -234,7 +236,9 @@ sub Create { #TODO Specify some sensible defaults. - unless ( defined( $args{'Name'} ) ) { + unless ( $args{'Name'} ) { + use Data::Dumper; + $RT::Logger->crit(Dumper \%args); return ( 0, $self->loc("Must specify 'Name' attribute") ); } @@ -274,6 +278,7 @@ sub Create { #If the create failed. unless ($id) { + $RT::Handle->Rollback(); $RT::Logger->error("Could not create a new user - " .join('-'. %args)); return ( 0, $self->loc('Could not create user') ); @@ -729,7 +734,7 @@ sub ResetPassword { my $template = RT::Template->new( $self->CurrentUser ); - if ( $self->IsPrivileged ) { + if ( $self->Privileged ) { $template->LoadGlobalTemplate('RT_PasswordChange_Privileged'); } else { @@ -929,7 +934,7 @@ sub GenerateRandomPassword { my $length = $min_length + int( rand( $max_length - $min_length ) ); - my $char = $self->GenerateRandomNextChar( $total_sum, $start_freq ); + my $char = $self->_GenerateRandomNextChar( $total_sum, $start_freq ); my @word = ( $char + $a ); for ( 2 .. $length ) { $char = diff --git a/rt/lib/RT/Users_Overlay.pm b/rt/lib/RT/Users_Overlay.pm index b397c3bc4..430e6d720 100644 --- a/rt/lib/RT/Users_Overlay.pm +++ b/rt/lib/RT/Users_Overlay.pm @@ -1,20 +1,19 @@ # BEGIN LICENSE BLOCK # -# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com> +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> # # (Except where explictly superceded by other copyright notices) # # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed -# from www.gnu.org +# from www.gnu.org. # # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # -# # Unless otherwise specified, all modifications, corrections or # extensions to this work which alter its source code become the # property of Best Practical Solutions, LLC when submitted for @@ -77,6 +76,20 @@ sub _Init { # }}} +=head2 PrincipalsAlias + +Returns the string that represents this Users object's primary "Principals" alias. + + +=cut + +sub PrincipalsAlias { + my $self = shift; + return($self->{'princalias'}); + +} + + # {{{ sub _DoSearch =head2 _DoSearch @@ -233,8 +246,15 @@ sub WhoHaveRight { push @privgroups, $Group->Id(); } + + if (@privgroups) { $self->WhoBelongToGroups(Groups => \@privgroups, IncludeSubgroupMembers => $args{'IncludeSubgroupMembers'}); + } + else { + # We don't have any group that matches -- make it impossible. + $self->Limit( FIELD => 'Id', VALUE => 'IS', OPERATOR => 'NULL' ); + } } # }}} diff --git a/rt/lib/t/02regression.t b/rt/lib/t/02regression.t index 62b4e9a69..4504cc76a 100644 --- a/rt/lib/t/02regression.t +++ b/rt/lib/t/02regression.t @@ -40,5 +40,5 @@ sub wanted_autogen { /^autogen.*\.t\z/s && require $_; } File::Find::find({wanted => \&wanted_regression}, 'lib/t/regression'); sub wanted_regression { /^*\.t\z/s && require $_; } -require "lib/t/03web.pl"; -require "lib/t/04_send_email.pl"; +require "/opt/rt3/lib/t/03web.pl"; +require "/opt/rt3/lib/t/04_send_email.pl"; diff --git a/rt/lib/t/02regression.t.in b/rt/lib/t/02regression.t.in index 51cd7e378..8c050ff5b 100644 --- a/rt/lib/t/02regression.t.in +++ b/rt/lib/t/02regression.t.in @@ -40,5 +40,5 @@ sub wanted_autogen { /^autogen.*\.t\z/s && require $_; } File::Find::find({wanted => \&wanted_regression}, 'lib/t/regression'); sub wanted_regression { /^*\.t\z/s && require $_; } -require "lib/t/03web.pl"; -require "lib/t/04_send_email.pl"; +require "@RT_LIB_PATH@/t/03web.pl"; +require "@RT_LIB_PATH@/t/04_send_email.pl"; diff --git a/rt/lib/t/03web.pl b/rt/lib/t/03web.pl index 4500ff281..94ad3e97e 100644 --- a/rt/lib/t/03web.pl +++ b/rt/lib/t/03web.pl @@ -5,6 +5,7 @@ use WWW::Mechanize; use HTTP::Request::Common; use HTTP::Cookies; use LWP; +use Encode; my $cookie_jar = HTTP::Cookies->new; my $agent = WWW::Mechanize->new(); @@ -15,7 +16,7 @@ $agent->cookie_jar($cookie_jar); # get the top page -my $url = "http://localhost/"; +my $url = "http://localhost".$RT::WebPath."/"; $agent->get($url); is ($agent->{'status'}, 200, "Loaded a page"); @@ -37,6 +38,37 @@ is($agent->{'status'}, 200, "Fetched the page ok"); ok( $agent->{'content'} =~ /Logout/i, "Found a logout link"); + +$agent->get($url."Ticket/Create.html?Queue=1"); +is ($agent->{'status'}, 200, "Loaded Create.html"); +$agent->form(3); +# Start with a string containing characters in latin1 +my $string = "I18N Web Testing æøå"; +Encode::from_to($string, 'iso-8859-1', 'utf8'); +$agent->field('Subject' => "Foo"); +$agent->field('Content' => $string); +ok($agent->submit(), "Created new ticket with $string"); + +ok( $agent->{'content'} =~ qr{$string} , "Found the content"); + +$agent->get($url."Ticket/Create.html?Queue=1"); +is ($agent->{'status'}, 200, "Loaded Create.html"); +$agent->form(3); +# Start with a string containing characters in latin1 +my $string = "I18N Web Testing æøå"; +Encode::from_to($string, 'iso-8859-1', 'utf8'); +$agent->field('Subject' => $string); +$agent->field('Content' => "BAR"); +ok($agent->submit(), "Created new ticket with $string"); + +ok( $agent->{'content'} =~ qr{$string} , "Found the content"); + + + +# }}} + + + use File::Find; find ( \&wanted , 'html/'); diff --git a/rt/lib/t/03web.pl.in b/rt/lib/t/03web.pl.in index abe446eeb..4fe2d3ef3 100644 --- a/rt/lib/t/03web.pl.in +++ b/rt/lib/t/03web.pl.in @@ -5,6 +5,7 @@ use WWW::Mechanize; use HTTP::Request::Common; use HTTP::Cookies; use LWP; +use Encode; my $cookie_jar = HTTP::Cookies->new; my $agent = WWW::Mechanize->new(); @@ -15,7 +16,7 @@ $agent->cookie_jar($cookie_jar); # get the top page -my $url = "http://localhost/"; +my $url = "http://localhost".$RT::WebPath."/"; $agent->get($url); is ($agent->{'status'}, 200, "Loaded a page"); @@ -37,6 +38,37 @@ is($agent->{'status'}, 200, "Fetched the page ok"); ok( $agent->{'content'} =~ /Logout/i, "Found a logout link"); + +$agent->get($url."Ticket/Create.html?Queue=1"); +is ($agent->{'status'}, 200, "Loaded Create.html"); +$agent->form(3); +# Start with a string containing characters in latin1 +my $string = "I18N Web Testing æøå"; +Encode::from_to($string, 'iso-8859-1', 'utf8'); +$agent->field('Subject' => "Foo"); +$agent->field('Content' => $string); +ok($agent->submit(), "Created new ticket with $string"); + +ok( $agent->{'content'} =~ qr{$string} , "Found the content"); + +$agent->get($url."Ticket/Create.html?Queue=1"); +is ($agent->{'status'}, 200, "Loaded Create.html"); +$agent->form(3); +# Start with a string containing characters in latin1 +my $string = "I18N Web Testing æøå"; +Encode::from_to($string, 'iso-8859-1', 'utf8'); +$agent->field('Subject' => $string); +$agent->field('Content' => "BAR"); +ok($agent->submit(), "Created new ticket with $string"); + +ok( $agent->{'content'} =~ qr{$string} , "Found the content"); + + + +# }}} + + + use File::Find; find ( \&wanted , 'html/'); diff --git a/rt/lib/t/04_send_email.pl b/rt/lib/t/04_send_email.pl index 46e3d7472..c384eedfa 100644 --- a/rt/lib/t/04_send_email.pl +++ b/rt/lib/t/04_send_email.pl @@ -33,6 +33,32 @@ sub RT::Action::SendEmail::SendMessage { # create a regular ticket my $parser = RT::EmailParser->new(); + + +# Let's test to make sure a multipart/report is processed correctly +my $content = `cat /opt/rt3/lib/t/data/multipart-report` || die "couldn't find new content"; +# be as much like the mail gateway as possible. +use RT::Interface::Email; + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); +my $tickets = RT::Tickets->new($RT::SystemUser); +$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); +$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); +my $tick = $tickets->First(); +ok ($tick->Id, "found ticket ".$tick->Id); + +ok ($tick->Transactions->First->Content =~ /The original message was received/, "It's the bounce"); + + +# make sure it fires scrips. +is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation"); + +undef @scrips_fired; + + + + $parser->ParseMIMEEntityFromScalar('From: root@localhost To: rt@example.com Subject: This is a test of new ticket creation as an unknown user @@ -65,7 +91,7 @@ is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation"); # create an iso 8859-1 ticket @scrips_fired = (); -my $content = `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; +my $content = `cat /opt/rt3/lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; @@ -74,8 +100,9 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. use RT::Interface::Email; - - RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -103,17 +130,21 @@ $parser->ParseMIMEEntityFromScalar($content); ok ($id, $msg); + + + # we need to swap out SendMessage to test the new things we care about; &iso8859_redef_sendmessage; $RT::EmailOutputEncoding = 'iso-8859-1'; # create an iso 8859-1 ticket @scrips_fired = (); -my $content = `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; +my $content = `cat /opt/rt3/lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; # be as much like the mail gateway as possible. use RT::Interface::Email; - RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -202,7 +233,7 @@ sub iso8859_redef_sendmessage { # {{{ test a multipart alternative containing a text-html part with an umlaut -my $content = `cat ./lib/t/data/multipart-alternative-with-umlaut` || die "couldn't find new content"; +my $content = `cat /opt/rt3/lib/t/data/multipart-alternative-with-umlaut` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); @@ -210,7 +241,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. ¨auts_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -229,7 +261,7 @@ sub umlauts_redef_sendmessage { # {{{ test a text-html message with an umlaut -my $content = `cat ./lib/t/data/text-html-with-umlaut` || die "couldn't find new content"; +my $content = `cat /opt/rt3/lib/t/data/text-html-with-umlaut` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); @@ -237,7 +269,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_html_umlauts_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -266,7 +299,7 @@ sub text_html_umlauts_redef_sendmessage { # {{{ test a text-html message with russian characters -my $content = `cat ./lib/t/data/text-html-in-russian` || die "couldn't find new content"; +my $content = `cat /opt/rt3/lib/t/data/text-html-in-russian` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); @@ -274,7 +307,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_html_russian_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -308,14 +342,15 @@ sub text_html_russian_redef_sendmessage { unshift (@RT::EmailInputEncodings, 'koi8-r'); $RT::EmailOutputEncoding = 'koi8-r'; -my $content = `cat ./lib/t/data/russian-subject-no-content-type` || die "couldn't find new content"; +my $content = `cat /opt/rt3/lib/t/data/russian-subject-no-content-type` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_plain_russian_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -346,7 +381,7 @@ $RT::EmailOutputEncoding = 'utf-8'; # {{{ test a message containing a nested RFC 822 message -my $content = `cat ./lib/t/data/nested-rfc-822` || die "couldn't find new content"; +my $content = `cat /opt/rt3/lib/t/data/nested-rfc-822` || die "couldn't find new content"; ok ($content, "Loaded nested-rfc-822 to test"); $parser->ParseMIMEEntityFromScalar($content); @@ -354,7 +389,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_plain_nested_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -382,7 +418,63 @@ sub text_plain_nested_redef_sendmessage { # }}} +# {{{ test a multipart alternative containing a uuencoded mesage generated by lotus notes + +my $content = `cat /opt/rt3/lib/t/data/notes-uuencoded` || die "couldn't find new content"; + +$parser->ParseMIMEEntityFromScalar($content); + + +# be as much like the mail gateway as possible. +¬es_redef_sendmessage; + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); +my $tickets = RT::Tickets->new($RT::SystemUser); +$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); +$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); +my $tick = $tickets->First(); +ok ($tick->Id, "found ticket ".$tick->Id); + +ok ($tick->Transactions->First->Content =~ /from Lotus Notes/, "We recorded the content right"); +is ($tick->Transactions->First->Attachments->Count , 3 , "Has three attachments"); + +sub notes_redef_sendmessage { + no warnings qw/redefine/; + eval 'sub RT::Action::SendEmail::SendMessage { }'; +} + +# }}} + +# {{{ test a multipart that crashes the file-based mime-parser works + +my $content = `cat /opt/rt3/lib/t/data/crashes-file-based-parser` || die "couldn't find new content"; + +$parser->ParseMIMEEntityFromScalar($content); + + +# be as much like the mail gateway as possible. +&crashes_redef_sendmessage; + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); +my $tickets = RT::Tickets->new($RT::SystemUser); +$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); +$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); +my $tick = $tickets->First(); +ok ($tick->Id, "found ticket ".$tick->Id); + +ok ($tick->Transactions->First->Content =~ /FYI/, "We recorded the content right"); +is ($tick->Transactions->First->Attachments->Count , 5 , "Has three attachments"); + +sub crashes_redef_sendmessage { + no warnings qw/redefine/; + eval 'sub RT::Action::SendEmail::SendMessage { }'; +} + + +# }}} # Don't taint the environment $everyone->PrincipalObj->RevokeRight(Right =>'SuperUser'); diff --git a/rt/lib/t/04_send_email.pl.in b/rt/lib/t/04_send_email.pl.in index e171cdc9b..2bdf4c5a6 100644 --- a/rt/lib/t/04_send_email.pl.in +++ b/rt/lib/t/04_send_email.pl.in @@ -33,6 +33,32 @@ sub RT::Action::SendEmail::SendMessage { # create a regular ticket my $parser = RT::EmailParser->new(); + + +# Let's test to make sure a multipart/report is processed correctly +my $content = `cat @RT_LIB_PATH@/t/data/multipart-report` || die "couldn't find new content"; +# be as much like the mail gateway as possible. +use RT::Interface::Email; + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); +my $tickets = RT::Tickets->new($RT::SystemUser); +$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); +$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); +my $tick = $tickets->First(); +ok ($tick->Id, "found ticket ".$tick->Id); + +ok ($tick->Transactions->First->Content =~ /The original message was received/, "It's the bounce"); + + +# make sure it fires scrips. +is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation"); + +undef @scrips_fired; + + + + $parser->ParseMIMEEntityFromScalar('From: root@localhost To: rt@example.com Subject: This is a test of new ticket creation as an unknown user @@ -65,7 +91,7 @@ is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation"); # create an iso 8859-1 ticket @scrips_fired = (); -my $content = `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; +my $content = `cat @RT_LIB_PATH@/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; @@ -74,8 +100,9 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. use RT::Interface::Email; - - RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -103,17 +130,21 @@ $parser->ParseMIMEEntityFromScalar($content); ok ($id, $msg); + + + # we need to swap out SendMessage to test the new things we care about; &iso8859_redef_sendmessage; $RT::EmailOutputEncoding = 'iso-8859-1'; # create an iso 8859-1 ticket @scrips_fired = (); -my $content = `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; +my $content = `cat @RT_LIB_PATH@/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content"; # be as much like the mail gateway as possible. use RT::Interface::Email; - RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -202,7 +233,7 @@ sub iso8859_redef_sendmessage { # {{{ test a multipart alternative containing a text-html part with an umlaut -my $content = `cat ./lib/t/data/multipart-alternative-with-umlaut` || die "couldn't find new content"; +my $content = `cat @RT_LIB_PATH@/t/data/multipart-alternative-with-umlaut` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); @@ -210,7 +241,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. ¨auts_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -229,7 +261,7 @@ sub umlauts_redef_sendmessage { # {{{ test a text-html message with an umlaut -my $content = `cat ./lib/t/data/text-html-with-umlaut` || die "couldn't find new content"; +my $content = `cat @RT_LIB_PATH@/t/data/text-html-with-umlaut` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); @@ -237,7 +269,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_html_umlauts_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -266,7 +299,7 @@ sub text_html_umlauts_redef_sendmessage { # {{{ test a text-html message with russian characters -my $content = `cat ./lib/t/data/text-html-in-russian` || die "couldn't find new content"; +my $content = `cat @RT_LIB_PATH@/t/data/text-html-in-russian` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); @@ -274,7 +307,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_html_russian_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -308,14 +342,15 @@ sub text_html_russian_redef_sendmessage { unshift (@RT::EmailInputEncodings, 'koi8-r'); $RT::EmailOutputEncoding = 'koi8-r'; -my $content = `cat ./lib/t/data/russian-subject-no-content-type` || die "couldn't find new content"; +my $content = `cat @RT_LIB_PATH@/t/data/russian-subject-no-content-type` || die "couldn't find new content"; $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_plain_russian_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -346,7 +381,7 @@ $RT::EmailOutputEncoding = 'utf-8'; # {{{ test a message containing a nested RFC 822 message -my $content = `cat ./lib/t/data/nested-rfc-822` || die "couldn't find new content"; +my $content = `cat @RT_LIB_PATH@/t/data/nested-rfc-822` || die "couldn't find new content"; ok ($content, "Loaded nested-rfc-822 to test"); $parser->ParseMIMEEntityFromScalar($content); @@ -354,7 +389,8 @@ $parser->ParseMIMEEntityFromScalar($content); # be as much like the mail gateway as possible. &text_plain_nested_redef_sendmessage; -RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond'); +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); my $tickets = RT::Tickets->new($RT::SystemUser); $tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); $tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); @@ -382,7 +418,63 @@ sub text_plain_nested_redef_sendmessage { # }}} +# {{{ test a multipart alternative containing a uuencoded mesage generated by lotus notes + +my $content = `cat @RT_LIB_PATH@/t/data/notes-uuencoded` || die "couldn't find new content"; + +$parser->ParseMIMEEntityFromScalar($content); + + +# be as much like the mail gateway as possible. +¬es_redef_sendmessage; + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); +my $tickets = RT::Tickets->new($RT::SystemUser); +$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); +$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); +my $tick = $tickets->First(); +ok ($tick->Id, "found ticket ".$tick->Id); + +ok ($tick->Transactions->First->Content =~ /from Lotus Notes/, "We recorded the content right"); +is ($tick->Transactions->First->Attachments->Count , 3 , "Has three attachments"); + +sub notes_redef_sendmessage { + no warnings qw/redefine/; + eval 'sub RT::Action::SendEmail::SendMessage { }'; +} + +# }}} + +# {{{ test a multipart that crashes the file-based mime-parser works + +my $content = `cat @RT_LIB_PATH@/t/data/crashes-file-based-parser` || die "couldn't find new content"; + +$parser->ParseMIMEEntityFromScalar($content); + + +# be as much like the mail gateway as possible. +&crashes_redef_sendmessage; + +my %args = (message => $content, queue => 1, action => 'correspond'); + RT::Interface::Email::Gateway(\%args); +my $tickets = RT::Tickets->new($RT::SystemUser); +$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC'); +$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0'); +my $tick = $tickets->First(); +ok ($tick->Id, "found ticket ".$tick->Id); + +ok ($tick->Transactions->First->Content =~ /FYI/, "We recorded the content right"); +is ($tick->Transactions->First->Attachments->Count , 5 , "Has three attachments"); + +sub crashes_redef_sendmessage { + no warnings qw/redefine/; + eval 'sub RT::Action::SendEmail::SendMessage { }'; +} + + +# }}} # Don't taint the environment $everyone->PrincipalObj->RevokeRight(Right =>'SuperUser'); diff --git a/rt/lib/t/data/crashes-file-based-parser b/rt/lib/t/data/crashes-file-based-parser new file mode 100644 index 000000000..da1913eb9 --- /dev/null +++ b/rt/lib/t/data/crashes-file-based-parser @@ -0,0 +1,193 @@ +X-Real-To: <mitya@example.com> +Received: from [194.87.5.31] (HELO sinbin.d-s.example.com) + by cgp.example.com (CommuniGate Pro SMTP 4.0.6/D4) + with ESMTP-TLS id 125035761 for mitya@example.com; Thu, 11 Dec 2003 15:17:46 +0300 +Received: (from daemon@localhost) + by sinbin.d-s.example.com (8.12.9p1/8.11.6) id hBBCHjN0031595 + for mitya@example.com; Thu, 11 Dec 2003 15:17:45 +0300 (MSK) + (envelope-from noc@rt3.mx.example.com) +Received: from d-s.example.com by sinbin.d-s.example.com with ESMTP id hBBCHjar031575; + (8.12.9p2/D) Thu, 11 Dec 2003 15:17:45 +0300 (MSK) +X-Real-To: <mitya@example.com> +Sender: <noc@rt3.mx.example.com> (Network Operation Center) +To: mitya@example.com +Date: Thu, 11 Dec 2003 15:17:45 +0300 +Message-ID: <redirect-137509289@d-s.example.com> +X-Original-Return-Path: <vox19@b92.d-s.example.com> +Received: from [194.87.0.16] (HELO mail.d-s.example.com) + by d-s.example.com (CommuniGate Pro SMTP 4.1.5/D1) + with ESMTP id 120757484 for noc@rt3.mx.example.com; Mon, 27 Oct 2003 09:40:53 +0300 +Received: from [194.87.0.22] (HELO moscvax.d-s.example.com) + by mail.d-s.example.com (CommuniGate Pro SMTP 4.1.5/D) + with ESMTP-TLS id 107945800 for noc@rt3.mx.example.com; Mon, 27 Oct 2003 09:40:53 +0300 +Received: from d-s.example.com (mx.d-s.example.com [194.87.0.32]) + by moscvax.d-s.example.com (8.12.9/8.12.9) with ESMTP id h9R6erFm062621 + for <security@d.example.com>; Mon, 27 Oct 2003 09:40:53 +0300 (MSK) + (envelope-from vox19@b92.d-s.example.com) +Received: by d-s.example.com (CommuniGate Pro PIPE 4.1.5/D1) + with PIPE id 120757490; Mon, 27 Oct 2003 09:40:53 +0300 +Received: from [194.87.2.108] (HELO b92.d-s.example.com) + by d-s.example.com (CommuniGate Pro SMTP 4.1.5/D1) + with ESMTP-TLS id 120757480 for security@d.example.com; Mon, 27 Oct 2003 09:40:52 +0300 +Received: from b92.d-s.example.com (localhost [127.0.0.1]) + by b92.d-s.example.com (8.12.8p1/8.12.3) with ESMTP id h9R6eqIe014669 + for <security@d.example.com>; Mon, 27 Oct 2003 09:40:52 +0300 (MSK) + (envelope-from vox19@b92.d-s.example.com) +Received: from localhost (localhost [[UNIX: localhost]]) + by b92.d-s.example.com (8.12.8p1/8.12.3/Submit) id h9R6epst014668 + for security@d.example.com; Mon, 27 Oct 2003 09:40:51 +0300 (MSK) +From: "Stanislav" <drstas@d.example.com> +Subject: Fwd: scanning my ports +X-Original-Date: Mon, 27 Oct 2003 10:40:51 +0400 +User-Agent: KMail/1.5.4 +X-Original-To: security@d.example.com +MIME-Version: 1.0 +Content-Type: Multipart/Mixed; + boundary="Boundary-00=_z3Ln/tUeUBipHgx" +X-Original-Message-Id: <200310270940.51758.vox19@d.example.com> +X-Spam-Checker-Version: SpamAssassin 2.60-jumbo.demos (1.212-2003-09-23-exp) +X-Spam-Level: +X-Spam-Status: No, hits=-6.8 required=5.0 tests=BAYES_00,FROM_ENDS_IN_NUMS, + HTML_MESSAGE,SUBJECT_RT autolearn=ham version=2.60-jumbo.demos +X-Spam-Report: -6.8 points, 5.0 required; + * -3.0 SUBJECT_RT Tracking system + * 1.0 FROM_ENDS_IN_NUMS From: ends in numbers + * 0.1 HTML_MESSAGE BODY: HTML included in message + * -4.9 BAYES_00 BODY: Bayesian spam probability is 0 to 1% + * [score: 0.0000] + + +--Boundary-00=_z3Ln/tUeUBipHgx +Content-Type: text/plain; + charset="koi8-r" +Content-Transfer-Encoding: 7bit +Content-Disposition: inline + + +FYI + + +---------- Forwarded Message ---------- + +Subject: [DEMOS #12148] scanning my ports +Date: Sunday 26 October 2003 20:19 +From: 1stwizard@isp.example.com +To: no-reply@d-r.example.com + +This transaction appears to have no content + +------------------------------------------------------- + + + +-- +best wishes, + +Stanislav A. Mushkat +http://www.di.example.com + +--Boundary-00=_z3Ln/tUeUBipHgx +Content-Type: text/plain; + charset="iso-8859-1"; + name=" " +Content-Transfer-Encoding: 7bit +Content-Disposition: inline + +Somebody at IP 127.0.0.1 scanned my ports. +--Boundary-00=_z3Ln/tUeUBipHgx +Content-Type: text/html; + charset="iso-8859-1"; + name=" " +Content-Transfer-Encoding: 7bit +Content-Disposition: inline + +<HTML><HEAD> +<META http-equiv=Content-Type content="text/html; charset=iso-8859-1"> +<META content="IncrediMail 1.0" name=GENERATOR> +<!--IncrdiXMLRemarkStart> +<IncrdiX-Info> +<X-FID>BA285063-5BCE-11D4-AF8D-0050DAC67E11</X-FID> +<X-FVER>2.0</X-FVER> +<X-FIT>Letter</X-FIT> +<X-FCOL>Elegant Paper</X-FCOL> +<X-FCAT>Stationery</X-FCAT> +<X-FDIS>Rice Fields</X-FDIS> +<X-Extensions>SU1CTDEsNDEsgUmBSTAkkcGNgZmVTY0wNCxNhYUoiU0kOMEoTYGBjYEoJDSZnSyFhUksSU1CTDIsMCwsSU1CTDMsMCwsVHlwZVZlcnNpb24sMywxLjAs</X-Extensions> +<X-BG>8E549F43-079D-11D8-B0F9-00B0D0B65B96</X-BG> +<X-BGT>repeat</X-BGT> +<X-BGC>#eff3f7</X-BGC> +<X-BGPX>left</X-BGPX> +<X-BGPY>0px</X-BGPY> +<X-ASN>ANIM3D00-NONE-0000-0000-000000000000</X-ASN> +<X-ASNF>0</X-ASNF> +<X-ASH>ANIM3D00-NONE-0000-0000-000000000000</X-ASH> +<X-ASHF>1</X-ASHF> +<X-AN>6486DDE0-3EFD-11D4-BA3D-0050DAC68030</X-AN> +<X-ANF>0</X-ANF> +<X-AP>6486DDE0-3EFD-11D4-BA3D-0050DAC68030</X-AP> +<X-APF>1</X-APF> +<X-AD>C3C52140-4147-11D4-BA3D-0050DAC68030</X-AD> +<X-ADF>0</X-ADF> +<X-AUTO>X-ASN,X-ASH,X-AN,X-AP,X-AD</X-AUTO> +<X-CNT>;</X-CNT> +</IncrdiX-Info> +<IncrdiXMLRemarkEnd--> +</HEAD> +<BODY style="BACKGROUND-POSITION: left 0px; FONT-SIZE: 12pt; MARGIN: 0px 10px 10px; COLOR: #00005b; BACKGROUND-REPEAT: repeat; FONT-FAMILY: Arial" text=#00005b bgColor=#eff3f7 background=cid:8E549F43-079D-11D8-B0F9-00B0D0B65B96 scroll=yes SIGCOLOR="0" X-ADF="0" X-AD="C3C52140-4147-11D4-BA3D-0050DAC68030" X-APF="1" X-AP="6486DDE0-3EFD-11D4-BA3D-0050DAC68030" X-ANF="0" X-AN="6486DDE0-3EFD-11D4-BA3D-0050DAC68030" X-ASHF="1" X-ASH="ANIM3D00-NONE-0000-0000-000000000000" X-ASNF="0" X-ASN="ANIM3D00-NONE-0000-0000-000000000000" X-FVER="2.0" X-FID="BA285063-5BCE-11D4-AF8D-0050DAC67E11" X-FIT="Letter" X-FCOL="Elegant Paper" X-FCAT="Elegant Paper" X-FDIS="Rice Fields" ORGYPOS="0"> +<TABLE id=INCREDIMAINTABLE cellSpacing=0 cellPadding=2 width="100%" border=0> +<TBODY> +<TR> +<TD id=INCREDITEXTREGION style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 12pt; PADDING-BOTTOM: 0px; CURSOR: auto; PADDING-TOP: 0px" vAlign=top width="100%"> +<DIV>Somebody at IP 127.0.0.1 scanned my ports. </DIV> +<DIV> </DIV> +<DIV> </DIV></TD></TR> +<TR> +<TD id=INCREDIFOOTER width="100%"> +<TABLE cellSpacing=0 cellPadding=0 width="100%"> +<TBODY> +<TR> +<TD width="100%"></TD> +<TD id=INCREDISOUND vAlign=bottom align=middle></TD> +<TD id=INCREDIANIM vAlign=bottom align=middle></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></BODY></HTML> +--Boundary-00=_z3Ln/tUeUBipHgx +Content-Type: image/jpeg; + charset="iso-8859-1"; + name="BackGrnd.jpg" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; filename="BackGrnd.jpg" + +/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFk +b2JlAGTAAAAAAQMAEAMCAwYAAAHbAAAC1gAABZX/2wCEABALCwsMCxAMDBAX +Dw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoXHh4jJSclIx4vLzMzLy9AQEBAQEBA +QEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoaJjAjHh4eHiMw +Ky4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAGUAcwMBIgACEQED +EQH/xACAAAEBAQEAAAAAAAAAAAAAAAAAAQIGAQEBAAAAAAAAAAAAAAAAAAAA +ARABAAICAwEAAgMAAAAAAAAAAQARIQIxQRIiQDIQMFARAAICAgIBBAIDAQEA +AAAAAAERACExQVFhcYGRobECEsHhMtHxEgEAAAAAAAAAAAAAAAAAAABQ/9oA +DAMBAAIRAxEAAADtRZYE1ASghQFgUZoCkKSwLmhcllAEqkSkqFAlhUomoAS3 +IoJqFlDNpFEAQFE1AIVYAWIVKAJRNZpYCwVmmshKACA0CBAUCBYGwf/aAAgB +AgABBQD8B/yP/9oACAEDAAEFAPz6/or8H//aAAgBAQABBQC2+ZeHjbD+saX6 +hwXeDW1Rg4xLLTa+m7ZiIEsI1MTiHP1dYpvFADiFM1/X6nq9byuwdPPz5oFo +fWlEMQ9ULKrWq2ppG9Y2J6INQma9lVTRdlUKgHzXXSEECw1SYu5WsGoJPkis +ZYpx31GvXZQ/JM3VwShzVTsp1EZbBI8LcaUSih86+s2Zl4Wp6+lAZnVsDkjd +ku5m+lJTdXDG2SHM9M2wKX1YxsaZTTwmoVrYnqsMrM652yjs01K0mtbGAz6Y +5dpfqNz06qpq5QNjiIjiZtbhtceNuf0jyeqGgu6rXMvI4omPWbPMYzEfMI+a +xHnFvOP4/9oACAECAgY/AGP/2gAIAQMCBj8AY//aAAgBAQEGPwB72Yucb1Bf +IhFEaeZ+xRXFQELN+HEUQdjU0Xn4g9gRCQcpw1yajGYsP/kFvUzvjUBWrIMF +HI2OJQNEAjiEEFdTmfG/MTHq5RFOnpTV3kzCBx7x4YOD1AV5uYJvnqMA0hep +jfwpYCwC4Bx3q55zeZRBCw9TkoIuHw78RdczSNH2mgqcLpRC+RASAkA3B13m +cYd5mR84c/yOx4lWtRAZ6mGDhiP9WgXVyhWA+xDgMOWGMsTg/wBTz8SjjXrP +8hHIlX1MZ6mDzgc/cIV/iyN1GBR0MQMKjnEzvvMz8mUkErKlfqU63iV+IKNH +7mNZBLFQEpEDeDOV32IVn8WR4caoywqI2p695mbZzNUQIcKfk0bo+0NpCqn7 +CiQiNGXkdQen1DpjGeZ7WNw3pK+I93maCPc16+Zkf6XxMCsFwAkaiIB57vc/ +IAhZ/HqZBBbB0ZokAEOGxsYqBgPp8agQBu4VSMJdqx6SwDsGBrTmAR93uZGX +6KePowEADAIjoX8gw459CICaW/MLGvodQfkDW71zBxRHtB3j3jC4PMIYoAgK +NfPMCQNN7jCzvlzXPopzhQvNZY3CRya9ZrEFfRE0iCB5mscZuVYfKmAi94uE +3Q8qfytQ7xD0svmFcmaxNPI8iMjh3pmF2HbzqeUi+YkiD/MrOl5LmbwPuWVf +mXpv3hDH8qAjPpiZHXkRnSd6ZhB53mejzKV6US0K9TCCLyCeIhtETX5MsHBG +JkD/ANiFkMCE2qGoCdZ8Q8AMGpYFqEhdhRIYH3CF3d1M/Mexma+4CwdQ2Ddc +x0exAlmj04QUQd8QWLB/iB5GxmEg5TENVZqPYzFV8eHAy9T/AEc8a4n3Ov6g +/VwvE6lpQ4VNysXzhS8esOO8w/rlF/rypjV3B5H1Knr8T//Z + +--Boundary-00=_z3Ln/tUeUBipHgx-- + diff --git a/rt/lib/t/data/multipart-report b/rt/lib/t/data/multipart-report new file mode 100644 index 000000000..538e0c880 --- /dev/null +++ b/rt/lib/t/data/multipart-report @@ -0,0 +1,66 @@ +Return-Path: <mailnull@example.com> +Date: Sat, 23 Aug 2003 00:15:18 +0800 (SGT) +From: Mail Delivery Subsystem <MAILER-DAEMON@other.example.com> +Message-Id: <200308221615.CGA36111@mailbox.other.example.com> +To: support@example.com +MIME-Version: 1.0 +Content-Type: multipart/report; report-type=delivery-status; + boundary="CGA36111.1061568918/mailbox.other.example.com" +Subject: Returned mail: User unknown +Auto-Submitted: auto-generated (failure) + +This is a MIME-encapsulated message + +--CGA36111.1061568918/mailbox.other.example.com + +The original message was received at Sat, 23 Aug 2003 00:15:18 +0800 (SGT) +from mx12.mcis.other.example.com [10.1.1.232] + + ----- The following addresses had permanent delivery errors ----- +<jesmund> + + +--CGA36111.1061568918/mailbox.other.example.com +Content-Type: message/delivery-status + +Reporting-MTA: dns; mailbox.other.example.com +Arrival-Date: Sat, 23 Aug 2003 00:15:18 +0800 (SGT) + +Final-Recipient: RFC822; jesmund@mailbox.other.example.com +Action: failed +Status: 5.1.1 +Remote-MTA: DNS; mail.mcis.other.example.com +Diagnostic-Code: SMTP; 550 5.1.1 <jesmund>... User unknown +Last-Attempt-Date: Sat, 23 Aug 2003 00:15:18 +0800 (SGT) + +--CGA36111.1061568918/mailbox.other.example.com +Content-Type: message/rfc822 + +Return-Path: <support@example.com> +Received: from mx12.other.example.com (mx12.mcis.other.example.com [10.1.1.232]) + by mailbox.other.example.com (Mirapoint Messaging Server MOS 3.3.3-GR) + with ESMTP id CGA36101; + Sat, 23 Aug 2003 00:15:17 +0800 (SGT) +Received: from STATION13 (rhala.dsl.pe.net [64.38.69.104]) + by mx12.other.example.com (8.12.9/8.12.9) with ESMTP id h7MGFGac020135 + for <jesmund@other.example.com>; Sat, 23 Aug 2003 00:15:17 +0800 +Message-Id: <200308221615.h7MGFGac020135@mx12.other.example.com> +From: <support@example.com> +To: <jesmund@other.example.com> +Subject: Thank you! +Date: Fri, 22 Aug 2003 9:15:19 --0700 +X-MailScanner: Found to be clean +Importance: Normal +X-Mailer: Microsoft Outlook Express 6.00.2600.0000 +X-MSMail-Priority: Normal +X-Priority: 3 (Normal) +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="_NextPart_000_05684DA4" + + + +--_NextPart_000_05684DA4-- + +--CGA36111.1061568918/mailbox.other.example.com-- + diff --git a/rt/lib/t/data/notes-uuencoded b/rt/lib/t/data/notes-uuencoded new file mode 100644 index 000000000..f27fdf8c0 --- /dev/null +++ b/rt/lib/t/data/notes-uuencoded @@ -0,0 +1,2368 @@ +Return-Path: <mhenrion@example.com> +Delivered-To: j@pallas.eruditorum.org +Received: from serveurlotus.example.com (unknown [213.56.193.67]) + by pallas.eruditorum.org (Postfix) with SMTP id C21DB113AA + for <jesse@vendor.example.com>; Thu, 27 Nov 2003 10:55:58 -0500 (EST) +Received: by serveurlotus.example.com(Lotus SMTP MTA v4.6.1 (569.2 2-6-1998)) id C1256DEB.00578401 ; Thu, 27 Nov 2003 16:55:54 +0100 +X-Lotus-FromDomain: DOMAINEQZ +From: "Maxime HENRION" <mhenrion@example.com> +To: jesse@vendor.example.com +Cc: support@example.com +Message-ID: <C1256DEB.005717B5.00@serveurlotus.example.com> +Date: Thu, 27 Nov 2003 16:55:50 +0100 +Subject: Test e-mail which exhibits problems with RT +X-Spam-Status: No, hits=-2.6 required=7.0 + tests=BAYES_20 + version=2.55 +X-Spam-Level: +X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp) +Content-Length: 144905 + +I send you this mail from Lotus Notes to make sure it'll exhibit the +reported symptoms (lost attachment and body). I Cc: it to our RT address +to verify it does cause the reported problems. Could you please mail me +any replies to my personal e-mail, mux@example.org ? + +Thanks in advance, +Maxime + +(See attached file: Naz_Head.jpg) + +(UUEncoded file named: Naz_Head.jpg follows) +(Its format is: JPEG File Interchange ) + +begin 644 Naz_Head.jpg +M_]C_X``02D9)1@`!`@(```````#__@`>04-$(%-Y<W1E;7,@1&EG:71A;"!) +M;6%G:6YG`/_``!$(!(D#$P,!(@`"$0$#$0'_VP"$``0"`P,#`@0#`P,$!`0$ +M!@H&!@4%!@P("0<*#@P/#PX,#@T0$A<3$!$5$0T.%!L4%1<8&1H9#Q,<'AP9 +M'A<9&1@!!@8&"0<)$0D)$248%1@E)24E)24E)24E)24E)24E)24E)24E)24E +M)24E)24E)24E)24E)24E)24E)24E)24E)?_$`*(```$%`0$!`0`````````` +M``(``0,$!08'"`D0``$#`P,"!0($!`0$!0(""P$``A$#!"$2,4$%4083(F%Q +M@9$',J&Q%"-"P5+1X?`5,V+Q"!8D-%,7<H(U0QACDI.B)29&5%8!`0$!`0$! +M`0`````````````!`@,$!081`0$``@(#``$%`0$!`0$````!`A$A,0,205$$ +M$R(R87$%%5*!_]H`#`,!``(1`Q$`/P#Y`NZSM9#1`&(!5%[G\U"!WW5B](U: +M0(GDE5'DR3$]R3,K53ZB?5?D$I,JNC=`\EN#.=PHMVZH^%$6?,)R3(`R90/K +M:AB0!LHFG"&6Q`,?*(E\^"`"3.=TC6=J`)([!0M#=1U'X3.TZ9D[X**G=6=( +MR82\]X,ZC`&"H0X"9<3W2:(&GOWF4+VLMN7D2T[[AR*E5<YPU?>56:T,@P<X +M3^D#'*J+3:SC(<8[92\XB/5]U7VV$E/Z=(!.459_B7`0'&2F%<EX)D]R%7!) +M:$B1.<S^B(G-PYFQQ/*7G$P9/M!5>9,:ML)Y$]AW03FLXR78A.VY=&=IV58& +M2!^X1-BFWO)S""S_`!#M,.,'VV2;<.(C48"JR'#&!V*>!LUV_OLBK)KO@C5) +M_9)M=V0(GNJSAL9"7!!E066UR&X)^BD%P06DOR%2&00WG=$WYSQ[JHL&Y&>9 +MQV3ON7.;ZG:@.).%59,Y.#[)H&F7.`/QNBK;:Y#?S$XP"4(N'[:S[Y46H-8< +M2#C.4``SZA!V")I9?5=AVO[<IA7=J)C$[DJN""8!VY"3C$;@(6+?\4_83O@) +MZ=U4;@$YQNJ0<>')L[3G?=15_P#BG`0"[/=(W;N3NJ@/J]>8PG=M(<!P%46Q +M<5)C5!&Z%UR0^=6_,JJZ220[',XE!J(VD@HJZZZ<3J+H)X*=]T]K1ZLGW5*G +M+G3N$[-()F/_`,1E0TN-N7@RUY)[R<)V7=1V=1^ZH@.,F<CA$V/+F8CLJBW6 +MO'^8/4[[HA=U,^L@K/?#GB-N4Y)Y)CW15RI>5'#_`)CL>Z`7CY]1=`[$Y50& +M1,Y]BF&^G!]I07_XRII!#JD3]E(RO<NI.KM-30T@.=P"LV`T[C]D0<?+(DD$ +MR0D5<;?59(+S)P9)2_CJN_F.)VR51=+7@S'QA($N$#9$:-.^JR/63]5(R]K. +MP*CM1]UF'7L,=H1M=+IY0:#[ZL'R'N$#9/\`\0N`3-1Q!.8*HD..1N@]0)@@ +MQ[HK39U"J2!YA`/*3>HU9_/O]5G,+F"9@>Z?5D3Q[HC2'4*PF'9=]T_\?6!' +M\QQ^2LZG,[R-U(3Z):<<"9A*+K.I7(<2*KA]4XZI<:R[S78YE9H))$NB?=+4 +M(C.^4&O2ZM<:Y-=^F<PXJ9W6[ME1_E5ZA!V]1P%A%T-/'NI*+M(U3J/LLU8V +M[?KM\#_[NK,?XBI7>(+\`#^+JQ[/*P/,<'SI`]E/1D[@'.`D*V[GKMZUP>;N +MOW`#RJEQXCZB^KJ_BJ_P*CEG]1JD5PW5D?HJC2`V8,]P>$A.&PSKO41Z'7E; +M/_649\0]18YO_K:I@Y]9@K%:\DDM/P.4#G._J)39IT%3Q#U(48;>U9]GE*WZ +M_P!3:=;KVMCC65@L,M],_=3C\I9@^_*IIT-GX@ZL]P<;ZK#3)EY5YWB;J9`_ +M]75`]G9*YJB-%&!@G<=T?F!K`T3'LL4=(/$_5-`TWE4#_P"Y,?%750__`-[5 +MS[KG?,U-`)..W*$N$F=QW4TKH?\`S5U?7)O:@^J3O%/5&`3>5<_]2YQS_3,D +M90OJ%L9S[*CI'>*^JA\_QE4>VN?[)4?%76`''^/KCC\Q7-.?WG[PHR\9[\!" +M.I/C+K8R.I7(CL\J1OC?K[!J'5KH>WF$+DC5TM&#J_="YY=].$Z'8?\`G_Q( +MTS_QJ\$\"L[_`#1?_4;Q8T"/$-^('_SN_P`UQ.O/`(3O?Z<\JZAR[=WXG>+V +MMQXBZB)Y-R__`#3?_4[QHV2/$W4\<?Q3_P#-<,YTD-[(7N!.70!NAR[S_P"J +M'C(;>)NJ0.]W4_S3?_5'QII.KQ/U0@;?^I?M]UPDN()DCLE2J/%6>?8Y5X-U +MWP_$[QDTZO\`S+U0#L;A_P#FA/XI>-1__D_5!`__`-A_^:XBK4+A#=]LJ'62 +MT@@2H;KO:?XK^.`#'BCJ7_\`'=_FI&?B]XY;G_S1U$]OY[O\UYWYA+")*;6- +MNRJ/26_C)X]8UI_\T]1@XCSBI/\`ZT_B$W;Q5?D]O-*\R#P`#O&R$UC,SDH/ +M4*?XX?B,R)\6]1$?_M4=3\<OQ&F6^+>HB?\`]IM^B\LU.W(D$*.M7\L$-DGW +M31MZF_\`';\2*6H'Q3U!Q(P?.V_15S^./XE:-;O%O42WDFIM^B\K#_3).0>4 +M1>-,R,YB86M0Y>HL_'+\2"X$>*NH?_Q/]%+1_'7\1FNSXHO2>_F+RG5#,F/8 +M=U(S+@Z23\)J'+VNT_\`$'^)M.W:QOBJ[@=WJ3_]8;\3_P#_`*NZ_P#WUX]0 +M/\IOJ`13_P!8_P!_1.#E)>;X.DJE4`G4&CW]U>O/2YTY/95"VD\@O(8(_-NE +M-(*I$\#ZJ.((DP#MRC?I!,.#@3P@<YLQ@D*)T!Y=!!'V3,!(!DR-NZ/!DDS_ +M`)H=3FOU#\Q$3*`2[U;F3^J9FG5DG!VA%J&"\3VA,PC.H3]4#")SCZ[IPZ6Y +M.?;*9Q$P1">`3L`F@0!<W48QB)RDW\W8=DM)B0,C=(G'Y3OG*H)A]7YC]TGO +M`;J&VTI8`@$@QRF`F)A`6HZ<&,(`XM$-),HM.TR`DTC)_9`@]H'?NB(U9)D* +M)Q`R/L"G:]K3D$_*"3`)DS'(_P`X2>0`")).=10F`,SG9*`Y^DS'9#0VZM.' +M@0=NZ51S@XYR=PG9IF'?1!4<)QF4!`X&<E.9%3F2.Z$Z-(:!$Y30-4SL@D`] +M<ETSPD2`X%Q$#W3.>TTQ@",3R5'[%V$1,Y\B8S&Q0:S^;4")R9@(2^`<P>T[ +M)`@^IH&GL%%2-?@B8^J;60">3]T+=C.J1O@_ND<_U8'(RJ<E))W`GE,?=Q,< +M%+TDD@R?E-$C#A[A0$`79&/JF!<U^X^B'!YRDUOJ(*HF#AY@Q&$6KDNB%"0" +M9!2<8.3)Y4$CW2\MF#^Z8.(;!&KZIG-P-L#A"V6F=8!/""0%I.0/<(75#/:= +M@$.F:>8`/)3#3OJ'T*(D:[&8B=Y4C7$"&M,J)L1Q'>$3@1L8'L@8F3@1]4+G +M&(VX2(#3^:>\%`?54P9'SNJHZ;B.^4]0D@X!(0@..QCZIR`V"7-.)0)CR6P1 +MDHFZ@-_B<H`WU1IGV3L#L0!`X)*:41=.<GX1,?\`TYA``=<C`&0EI/,90&PN +M+IQMR437D#8PHVM)B'>VZ.>9&?T32';4C&4FN.24S!G,B.4@"7P-D4;CZ02G +MUQM@'E,`7,D-F-TP:03#B)XW03TW0`3/=.ZHT[20HJ0(=JP<83U=1'Y??=$I +M.>20)B/JF<\D^W<!#)DQB>$)+@3@D=@@.1J(C\RGI.TTAL`%!;@U'@&8)4U< +M#40..%*LA!WKD@?,JQ3<*;=6J?959U`<%*HXBG,R=MU`JM05+G42#[QLF>8: +M0V"1O)W4;):`V3G>$4@$&()W0/YA+H&$S"=Q$'E,X34D!.&MF<>_NBIZ.G5. +M1C=6*32XZSMP56:Z#I#1/=6ZKAY8:!$;PI:1(7B!)SV0O<T[&(0BF-&<#W05 +M7:G%L8&%!,UPC`$_*?7)))4+&NF9P-@0G/R,]D!$M)DGX"3G%P`W^NZ!A;OB +M1[R@JU"1F(;VP4!ET'TD3[("8?&,^R`O!&,&=@A($`P2.TJFAQZAK/V0U()] +M),\A(QITP/C>$+R(+B![(IY&DQN$!U$=OE*99G;V0ZVDSVXE7:0I$@DY12W5 +MF0.P47ID%(N@03]R@.1DL'ZH<X)#L\RF$;:O]$Y8WR]0J-+I_+&?^R&A.=`G +M'T0!\2[)*%P,1D`<(7N`@$_JB40>#_DD#^G"C!R=_NE()$'?!0$X%Q$?NF(& +MY!&.Z;;4`24#RYH!!)]T#U7A@,\JNZ-6?ND\EYDN$]T]-[\MUX[0M!/;+?E, +MUDQ/WW2=4TGL3V*!SAQQS*(D:WD$P?T4M+8@29W]E!J],CE'J&H`.XR$&G0< +M!1:(&R/6WL%#1TFDTEW'9%#/\?Z)N+I/<F"1,=]7^JI5G`N(';`[*[?$.<7[ +MS]BJ=8@'&$J('2&YF3QV0`-+`XD3VY1<D$@'=`T>L@B%`B9(SQF$/&TIHT[B +M2F;!.3'L4#N:&P[?Y*:1!WD=T\S(.3\RA,:2Z.?T3:GD%I&Y&/A*8&9CLA(S +M$B/S8PG<V88QIQGOE$T-CV#9SB>Q&R<Z09CW(40V@#9$=IP/>%0;B#F#CW14 +MXU>QX4?]1X*3,$X(]U!,_2'0XS"%S@'20(CLAJF'#E)I!!:2J$XMS(]L(26P +M)S[(W._EENH@3J4+FR2/902.TZCP(V[HH!!C(*A;#@)V[<J6F<R3J&,3NA3@ +MXW*8",@'(15&AQD8C.\H>8@M^"J#<1&QE-SL0.Y2(SOLE'IF<($XB<F/="8+ +M(<<3$I/TD@`SVE!I].))"@-S@1(=@I"=)SNA((80#*(/$`M:!`SE%%,`#7&$ +MCN"YT_51DNB`Z0#CA.0X_5(AQ&`23[E/L1W/"C@.).T9*3S+@1/9/\.AM!.2 +M0">$3P0[)"%VD9!D#<I./I[IL2'5$`R$!&&SQA"UQTF73/'"?.($%#8Y&3// +MV35`XOU&)2):`?3!'U0O,M$B`>^Q02!D;F2>P0&(,[I,:XB-4B,Q"1#@=49" +M`J9!R^3&R=Q;J$(0(GD(*A<(='U2"1V&;#_-`R(D;%,\DL$B>Z$;X!55)G48 +M1-'IS&VZ'48&#GE,<C<0@(`:\`QVDI`;[<]TP=B00G:7"<;\A`;M1:2,8R<I +M-&0)@H0XZ(<-(B>4[2[5`(GL902`.:#ID(2,Y$D]D33Z().$(F,'ZH#:"6GU +MB9_*F$SO]$F-)V,%(.Y`D(:'4P0`?LD`[2)D`]]B@#LX:1*<O<&ZH4$C9&YP +M-LIW.#6R'&>Y0D02-.>ZE<\NHM`:)'/*HBDQ.=MYW2C,D[(2XN;))"32XM(! +M@'906+-LEU4DXF(2TD$$.)3AX91:WDY0DM#?RQQNI5A]!+@3/PA<=\@HGNCT +M_?/"AJG$#8^V$"UD8!4E,P9;G':5$"`?5()X4[6.@.VCLJ@2UT`B?E.3#`9$ +M\93:H/I/SA.P-J$``R#NH+%KAVLOD=H4I<9@SW[*(0T>EV/8)5'$N&9![K-Y +M5+J<68(R-TTB=0P4!<-`@(`YVH24$],SF?A"]P#MQG&4&J'">$+W>H09SA%% +MEI(D"=RA+9;D_;!3.+B\DCG9,]X(,.T@;?'R@6Y,]L94L4_X4N=Z7R(`V4.M +MPR2W*=S@:@&P(VE5."?KTR1!)F4#LB"-LRBG<B2[L@>YH`$85"!G@'ZIG0<D +M093'&<#@"4%0AI@D`<`=T#D1F0/N4P!!@#?>>$S8D3*L=2_@!58+)U4MTC6: +MD3JYVX00'T[YS\I4W`\H9#G"8^`D\M#AZ9^40Y<7'@?.4#@)!R24Q,]FI$ZG +M$_W5#XW$S'=,UHF(W0DB#DY3R0V29(W0"78)*KU':R`9]D]=^O\`*%&60\1P +M@,#5`VGNG`:T.,9!30`!#N,I0!N(`5*.B*/G!U5ITC)&<_91N+<D-)[0FJ/D +M:08`[H]#O+%0QI)@9S]MU`#1+A,Q^RE9'FD$'M'91@MU&-^ZD9N-.,;JHNTM +M(I@02B]/8H:=1K6``''LB\T=C]D.%FX.EKA@B,$JE<`AT3SPKEXZ"1&?M]53 +M>!J(G`*54-6=H"B/I?MDA2U3DG&.%&]Y=!+H(/W4`N_/@&$B6R'#=)[AJ(P( +M0-$/@"9303HF0TR/T2:06!I)E*3!$8E-K=K!``;QE`0#9`P8]L(&_(CV*<&0 +M<C.X"9Y]7QB0B">.9.4[OR['L"A<1$`A&_\`(.!.854F-(:?4?A$6AKX[;Y3 +M4G.#,[=RE.!(CNB'=&X.R8F``,)2X',0)"B)).T245(..>=L)B<D`#M`3:M( +M!=,@)Z1!?F<'_50)K1)!Q(V[J0#3B#F,(6.;KV(Y,%)S@0UHQP54['4<?B,H +M69)!/M/=)I(AS@8VRAD:P!CNH)<O/ID$<)F$APR?A-JAL2?NE,9P(RJ&=.H\ +M&=I1-$`N<2)4=1\F03_F4=,X$$E`SP-1$D0A$C&(/.RE(:7.<-_?A1D&8&_O +MRHIWDZ2-1&GE)C@TN!.3^B3=&D-(`_NA,-<X!V"(E$(;S(SV1/:]CAK:1(D> +MXX0'<B$;WZC@N(C??"*6'")R3_LIVN`S(,(&N$#VY2$G(;DX0IR3[2.R<.DF +M!!_=(D!@')R?=-/IDD2>R!SAP),>R1Y(SV]D+V_S2V))YE,T:F@`X"J)&2UI +M'._*1Q$&/<!,(C_JVV28(:<0.5%Z%J)!)W`R5&).!&F4;@9,Y![<*,#!,[[! +M!)IFG)?Z@8CV0Y`T@C2A@3NG;Z3\<DJB2GOO\Y0S(`(!)[*2E2<^D][`3HR2 +MA>7:9,`;0H&WR`(.(1;;D",8*:)Q)D;F4B#.'8!GL@?+7$'OPDV"_.3.Z6"1 +MM]1E.ULSD2,90$TES#\@83M&3&W=,USA$R0=RG`T@.!WVA%Z$UQ+CB!Q[I.( +M.`([^R<.EFW/*`DEYDX(@RB:%.8,&/V1MD8R<*,B'`[QPIV#^43D#]D`Y#H. +MK`Y"*J#$F028DY4?YJN,`=N457!<=I&<H:,]V)X`WA'3#L'^F=OA0@2=AE3! +MIY=$F-DIH3CJ?K(V/")H$>K/919@P1DJ5^EEO`(G(W]EEI%5(+ISE!4=D<$' +MO"6OU1Q*:)=G!Y5036G7)VVE76.<+5S1I')=L2J;"00`.5,S\D@C2$^!JAQL +M('LCH,<&E\@$YCZ(6-UNB7$!2@[-&`-]U*';.2#`CLE3'I$@'O/"8P!G'=%2 +M=J>9^<J*>L#$#$8P@:3DD@J5X<##?Z9)([J(?F_+)B<H'#@203@9P@GU';/9 +M,V&R0,)V9SC&4(=X<'#,R.%&3#0XC$P$3\N(`V^B&GM@XVGO^BL!C!`&GLG) +M:W!@Q&>9E`#IG<`\2FEN=L?JB%4($Y"!Q#8&1[]TG26`Z<`;=DG0&C[HH0,R +M<?)Y35&D.(Q!V]T\C5($@#(*C>('(.\*H?`@'O.-T+RUOIW,Y@J:XHU:5.G4 +MJTRT5&ZV3R-I^X4+H+B<Y']T`O(;Z1N.1A*GIDNP2>XE.3J('`Y"6&M^NZ:- +M!)RYV0"G!``&DB1DH8&7'`,C"8N],ZAP)0._2XB`94%5\NTCGE27)?2+6N8X +M:A(GLJ\`F)S^ZH8P!`R-Y3G\V)D#^Z0(&,F#O[)IY)A$&T@&08QRF=!:,$3& +MR<^H0TD$_JHWY]!W^J!W-);!&#NG.EI!U9!VRD0)`G/"%P;$@2(0&!%0.F09 +MG*.F`#^:3O""FT$`D[X^5)1G4!@GL54K1HU8I-!F81><.Q48H]W9&,92\D?X +MBJ<+=T&!T-,R,:>%1J!DDQ,=RKEW`<?OO$*C5/IDG._RIEVJ-_J&IW(A0OES +MRXF(X4E0Z7&"@<1,[\DJ`'`E_ORFP=C]?9$1#@9R.Z%_]1`D%$,?R:@WV^4P +M'IP<<RG@@>Y,X1/]1)!`&T(H6Q'..QW0^^Q]D1/],`X2!<<GY0(F""9]I*=W +MJW,H`)P08'MF%)HSF2$03&`M(DP,D),+@(!GA"X:6D#/PF&XP280V1:><_\` +M9,2Z?RC!X1%IRX?=,-R<G&44B#JU`$=\[)Z8]1,!/MC2<^^$FGUS*H36#5J@ +M>PF$\>HC()V2<'!V/ZNZ%WYL#G[J=D$W#=S')'9"-B=C*+,3JG[X2:#C(SW5 +M#M(U>TIB8P"!GE-F<F2.0A(P29RH@HVC?=&PZ03`)G[(2&R`"B$!XAV$#G)S +MB.4+XU;P-]^4[MB0[9`XXU`^Q"*%QB"79C&4AAV^1^R0,#3L92<3&=T"!VEQ +MR8PF$AH+73*0D`XG.4M0:X#2-X0/.CC"(.]6/R]X3"`<[I-;#8G<3]43_"=, +MZAE/,M(C?NDQTMT_E'9(X;D@$HH1(/.T;)VQF<&<E-!UY)`^-U(R0)B1R)R4 +M-&:/3O,>V4[`6QB3[!%I=H+P"&SM*6HZ1'',($\PR(.3@A0P9)VCA&XNG)R< +MPF,$02,?HB$&XD_7NF@',9[)2=CE%`'LBI#5J&6ZX`&PV48>-7JV`_5/HV@? +M/ND02Z7?TG[H&@#W._PB@Z@):1'=.)>_)@\^Z%Q/YG8(Y0%@$@N`G$#NDTRU +MT<\IAB3.3G>4[7"#N0).$47]43.)_1$PB(C$J,8#8@2C9,SM_9-(-@]$`X.4 +M),C`(#433@M]S*&)=&<]D!TA)S^O)4U9H;;AHDSV4%(@`;F.%+6=Z`>$#,$. +MW]H*8DDDG;M"'S#C2,#L93R3D"2@(0'#5$B813J<6R/="P'RR22!P$S8:^)U +M3N2I5D2'3,1B=E$^"[_5&YP:6@A19F7#"FE$`8`'.91%IJX$B!RGI_FG)C,! +M$[\LP?8@JHC@M#OS23W1EQ\L#&IW9"XR?=3T*;=1>/\`,(:%0:6CDR)_LG<0 +MVI^:.=U-TW^&_C!_$BJ]G^&F!)/`SQ*&]=JJ%PHLI@>G0&Q`[+*HR<S!Q$1V +M2I8,S!WRD_@^W9,Z)W.!R$$SJKV,<`2)PHF:@09&QY1-_*)SPA(&Y,$X0`:A +MG&V^439))!B-ONF>-1R?9*EI%3+CGA`FEQ<XR/\`[=Y]U')!(P8'U1@M!_*/ +M24-2=0(CZ*APXQ$^\\(9D%HYQ*1<X52[4<\SND\Z3D$1[H'JDBCD`9W49>-, +MF)V^4]1PT;DD\("XZC'`50@_U#A!)@S.=H.R-[A$0@#@3+>4@=[M3`"3+1&3 +MPA.6:8R,9.Z6`-1.)0D#\VK3\;H?].02[!$D)G3IG4)/[IO=HE(@@29^B:*1 +M/H+7`P=@HW5"`/T`3$Z0=1.=@%%4(+OR[[JAWU'P-1,1@=DP=#L"1L"F`]$$ +M92S)'M`0$[!!!(GE".2?L4A&LD"('=,X1!D%"<B#@(XCW2U9.-\D#,I!HX;` +M3%IF,=Q[JAG'U`P=7NBU!QC?]4="B^L:@:6-T@N.IP'[\J(D8;R#DSNHFA`, +MU!L'&P[%2TY:X\Z3E0@@.#IF.94K&D.#OJ51>HU7-I-;)V1^>[N5'2CRQZ47 +MI_PE39__`%9N'D/=#RP$&8Y"H5B7`Q!`5V]U$G<-E4:N9_:%:(B!I^,B5&X0 +M,G<X")Q,EHP.T*-Y.N3E3M">TF`/U2]$&"9A._5IR1"C.-B?A!:Z76MZ-;76 +MIZQ!@1.?<**Y(\USF&&N<2`,0%'J=J&`.9*62XD.^J!9($../E)PSD'YE,XD +MNDRB+6Z))`)X'"!-B(+A(3THR2<`Y4;?2Z"W[HV^Q@^Z"S>OH5?+\FB:4,AV +M9U'NH-!D$`CW]DAD`';W2DB1/"!'TGA(3J&4P^#M".1Y8](!)C5R@'5#N8([ +MRF$1W[A,^-A)A)L[`9/97L'3`,^J/9.08^>4(])@G$Y"<OQ''N5`4PTQ!^4$ +MD&=7"1<`-MT,Y)_=`33(R[9,'D$]BF<1H&($YRA82XG`[!!('29&%/\`RBQI +M8\E_(55N'0I&D<2(SW0'4\P[Q'NA=ZFSR/U3%W])P=\H*C@#(&>Z*<D[G<]^ +M4GET9,'ND'-)!,@'E+C!D($W\@@DGNG]4G'/*;:8&.Y0.X02$EK<<)-/IF<C +M"%I(<8)!/"(9B.40]$_TPG^1,80L=)V2<1,D2500D$@P!RC`_E[0%&'%QDHV +MN.?[*`M;M&((_9`7&#Z?NC:^&;Y/":H6^6#MG:=D`L).YB?>$U,AI)+)]I0N +M($[3[IV#4'`D-Q(0,-\B/E.2-0Y[H6D'?CB40(B/LB[."7&(`^2CDSG([(#& +M'$Q"9CFAWM^J"0D"=+O_`,(2:0?S8'<(7?D(9/=.TC>4!'_F?&P3M<"P`M)^ +M2A:2?Z))^J<'.PCF4!O@Q`C&TIP&C+2<H:L0#&^$I`P=O9`9?-4FJ3`Q(3L( +M$P#"C`WU$8[J0;XS/!0('21&_=&'M,G`GOR@I-+\0,]\(@2<@"0@8M:9,D@" +M)".A3>\:PUQCF$``@G`)[C"ELW%E20.,%`U>)(,[<)FZ/,!R8X2;-2H07'/) +M35&C9@R-R"LJ:Z?JJ2TQ.P*9CR6^H;8A`6%P&H93M(@B2/A4&7NSI,81:VBD +MT'NA$@#!":,:AN@DID/J1$QMA7':12TM>2!C3W5>T8&F7#<9A2G2'&-H6:HF +M$MRTQIY&(2<YIV,F<GNAV;VG8%,[4!L0$"+V!N9DA/3=@'5*9^EK1DAW/`0T +M8TDR@DU`8!W0X)TR@^1CY10!ZCD%`TF"3$;(>Y(&??=/Z=XD#W3TV4RQQ=4T +MXD")DJ@=,TX'U!&4G%L@D$GB.4G$EH``B(D(20!I`@2@<N;!&P[90MR<'ZG= +M"Z)`F)Y2>R'8F3]95#U`"TZG#V0,PZ8$?*0_*3J.-P4.H3D0!PF@3F1(D%!` +M#?2_=$]K1SO[H"V`3[\(AA^724AEN(":)$G.>4Q`!+I]D(9X$21N8^5(:C?X +M=M(TV`M.K5SMRH@T22YQ([RHZKPY\3LJ<&J$D[8&<8E1P-8WA&]L1O\`"$M$ +MG]B@*#I/;N$AW.2D[)B?\DQ:6MW0)L3!E+2`X<#;*;=VK:$>F6R3\(A%I`R) +M!0./H)X]RG.N8:Z!V"`G_J'Q*+L[20"6N`'*4-+IG;@SE+3ODD']$T@;$_=$ +M2!KB3!)PBI2'1D3P2@IO(;@[CDJ1FJ<F>RHO4R`P`MV]T6IO^']4%/5H$3]D +M_J[G[(BS?.:1O/Q_=4*S@XR($*W7+M6,?14;C\Y&DGY5JHWU&%NJ(^%$7-#I +MR0.$YVWPAR';@1P0L[#.=,D$IAM,I.P/5L4FB1#<HA\%LM.1WY2IN#!,"8Y` +M,(>^2(14?+TDO#@Z,0-S[H!D$B3]CA/Z9P))XF4C`.WW3"`[9OP-T!:O5I.( +M1#,9Y0-`@D'(XSE/I$3O&=T$D9R0,IJD<#`[(7B!`B$=(,\LN/YAPJ'I!U2J +M*8DEV!">H?5$Q'=0OB=C\IV%LB0?NH%J&`,?7=$7-F2?JHW?G@`QS"?1J@9D +MJB1L.$EWZ%,XAQP)]X0-P-!DQ[E(@3B4#D09!QP$[BTO_P`/LHR`'01(&Y[) +M`-@@GX"@,1M(*>`!.('9,`(B-]H2>WU3)^$BCH,+@ZH&ZVL$NCA"!)W.=D`D +M'00[W1:?^HY]T00T[$B?E+3F9$]D).ET.]/8IC_TNYG=4.W!CT@C8%%B9G[% +M`X-<R6N.N=CLG#@&`-&D]QRBE`'YMW?JFP!,@_5`!)U%TPGR9$X*"0P693-@ +M?Z(!,Q)E2TFZJ;R)EL&%-!\0`#)[)$2-OL@,GU`PDP&),`GGLB)6Z2,3CE)C +M!/K='O,J*($@X.^5(&.))B1SA-B2"!I$Y358!R(E#)`.R%[P70W[=D4G#TG& +M90AI&3F4G>QWW":(W(*(-K!L-SW3U"<9P$-*9!=.$_J@DG!]]U03HTB1*%D! +MV3RA;/<3\IVM($3R@-S9'SC*?3&<GV0L<>2=T\S)XVC=`8$"03GW1`B3.2>5 +M%Z_\7UE$9`$\\I%&X"(+H[(@V!+=O9!,M&04B3.`?NH#C5MN4[!G<?"$O=$# +MA%ZM.K<JFSN:22<>T)P(;.#W]D`+RB),[[Y]BH!((!$<;RI`T#^J9$!"T@5` +M73],HF/=,Y!^5*IV"&^P1.!@:1]45NUU6HUC07%YC9=5XA\,ML^@T+NWU.>/ +M^;G8(;<B\1ZHDE`]K33&"'3O*L7`)I``[;X4,$#)P@4X$[IZ;7.J0`F)$!HG +MZE3V[?+]7/)02.>Z-,$1V3=I](*4R[5!^H2?CC(S,+*E$.YQ\IW`SB<[RDZH +M=S$H"\:).)[H",QB8W[)I+1)Y[(=8/!TQPG-22TP2`J%F#W"9@)9'*1=+>\E +M(&,\(!J-,B3CVV3M\H:PXEQ/Y<PA+FEI$X/ZI:R0#P/9`M3G-+-6V8"$F3I) +M4C'28'I("C>\-&"#)[H`@DZM0'UW4FC^5)W/*`N;,@Q.QA25GD4FM+@0-E1$ +MT%(^HYA,YS8$G[%#4>W5G,>Z`J0+WP2T?*!P+1GGA"7Q//NB#M3I=$#N@%TD +MQ!RG:USCI`)+N(3!X)[?&ZBJU@`()U`]U4*N2'Z9/V43_>$^H&3,<E,2#@DY +M0.<F(,IR0&['*#4.47HF0!'MRJA-<2(X*1,E,7``CGLEJR<J!Y($<(0X@1Q\ +MI@8D).TM;W11&/H4],M#7`_1`(<S!QV2;!WF408(SC(0F1.(GE*!,ZM^$8-$ +M4OR&9R^2@%D-/$?*FI.=,PK_`(;O^GV;WU+KIS;MQ$4W>8YI8?V(^BJA[#<$ +MAH:'&8_LJBRS\H_-]"G^CONI*8.@:=D\.[JFCU]&K))!6=<?.RM7;W!SLM!& +M?=4:CP!)Q&.RS5#4<<`"04#G21.4GO<&P,#V35`=>D#;.>R(:);)D92TYAQ( +MA!K]&DXGE.^IZ]1.Z!R!,.)PF<9,R!\IB[N)^J)Q@B0W81D($^7.DD.)RF;^ +M:)@\04P))P!/$[):])!/?=%'`WGZ)W21Q'8*.G.HD;GNB:^#B`"$B#@D`0/E +M)K3&'8Y0M?`!$%*F_.VRI$KJ!IL8\/:0\2,R1F,J-ATY_1,2.3GY3/?+G.TY +M*BG`DSRI,MIZ=,3O[J/5&",I.>"W5'^B"322V<9V*'!=`R1^J8&<B&CV2+A# +M06&>2/ZD0[V@B&#$X3P]N)`U;CN@U0Z2)^4J;QKEPD?/*`J8$8W3G.^.R&1C +MD#9,7("JZ]6EV^V4I]6T=RH^W/'RGUB`!L<(I'7$YSRG+8XF,X*'40P`#,I% +M[33].LCW0&?R`G?A.]L8&2>R%C@21$QV3Z@1IB/D[(&>),SO[I>Q$)B]H<1. +MV)28<@%THAR8;M\J2A7?1:XL.7")W46IH:0D'M+<`Y0&T^H%PD'=&`"2"0!\ +MH&N!SF2,E.UX+>/HBBI-8714<=/[(]88``R)P8*B#MO5]$S'%I)X/?\`[()G +M?E(#<_J@(AA`S[HO^:XBF)`R8[=U%JP1(A`[LNVVX3M:#]DVK.0!'*9KP'D[ +M(@H),`E.[:(@[Y3,(U9C&-)2>9S@1P4X4F3I):)C,)__`,4)VN&DQPA9$:9B +M>$T'`R2'8^$;&SZ9^J'>=(,?ME%OVA`U,,#<C?ORIJ=,:H,=P%'`<^1D=R-E +M*P@-G>4`09+@G>`3@$?(1@M!)(WY"3CB8&>4#.C@P1S")T!QS(3-=C2(SR43 +ML.:"=N`B!,1)<E'JD1!/T1:(/K*38+ITF!^B+#,<!M@\93LT3)=D;!$Q[F&6 +MN(/',J%I&F!N?E1IJ^%7@=<H/<]K!3>"3JA>B^);RA4Z'>U650PD"F`>?9>5 +M,:0[21!"MUJ]>G;MM:CB&-,D'!!*K-G*.H3Y<;25!+M1G96*CFU&@-!$;F=U +M#6;MF)X470:;"]_J,0%9!ETM<"/=10&MW$A'Z2"1.,PI06HM9I+M^YPDYVI" +M-(W)SPDV)&!CLHIH<3))_P`DY=-/1((!^J9^_?5]4[9PUS`9._=4`TP,#;A* +M1K./H$;O*#X9VV/=`"0\@8/)0(@@0D-3H!2V.9(F/A!L3R$!8+#$2-\;H9(S +MJR.`E`TQ.^Z1;Z?3QA`F/(!=@\Y3$MEWOLF([;'VW0D@$1N3,!4.T@C+FYX3 +MO=#(:Z1V0.$,G8<ISH`B2>WL$`Y_J'RFT@&>QV2<3'YLM3``3!^$#$$3$)BZ +M&C$\)-$P(.4#W9[J@G8+CO/"K/WVS\J0R#O]"FT:<@C=$!$X''*3\")`"+2! +M_6)[[(3ZAGO"!,@1Z8)[A(F#@#(^4Y$@-#I*1WF2/:4`N/K&!/LGT`.$I.)! +M`;N>$Y;@B9A$[",_W3$>D0#*(&"?9,V3OP@30`22#^R0`DX3_P!)DI$``.(P +M?;*='!I^<^Z><P)^I3:8.K_91.R9:,#.4":[,B1*GHRYP)!+?E!1`#@:@+AR +M&F%+0:21)`GVV6D:%N'&BTAKG#O*/2__`.-WW3TZ)+!,CZE/Y/N?N5>$X5+W +M0U\`&!LXB/T5&IVP<[;<J]>Z=;HG'?95:H<6N&J`-_4LU5>J6R=(`GA`UPU3 +MSP0C<,'T_=!I,@$1/"BE-,$:@2W8B>4PC2X:=_N$B#IEP&<PA:(+N/E1"=#6 +M:MP.$HT[Y]T0$&/NF;)!Q'P531_26@#9-@.U$Q[!.#)R,PA=F,GMOM_N4#\2 +M`#/"+2W48!RDUN9F<[SNG9^4`JA3+6M+6C3LAV<=Q"*H/5#<M]\(1EIWX4!& +M)&F(.Z9X:#N93@&,!$]K#&)PAI&V0?T@IS);,SRAW=O`E'`#9VT^Z!-C2,`# +MW0L#6N]61S[HR"!O^9"\^H``GZH$/RR8R=DOVC"+27F2Z"A].@"<E`XV`!W[ +MI$RR!$!/R0"/=,\0W,YY0`"9'Z)G#(AWM\IR,.)&>/9(#U`SL4#M#G"29(]\ +MH2(@29/8HV-BGJ.T[IG#TG=`-,0W&?:43@Z"1J,')3.PPC^KY39`]C@^Z!P6 +MP<;^Z;MW[IS,$AWU*0F2<!`V8G`A.W$D1E.(CY2<X&)@1&R!Q,D.(QE.);C8 +M'!GA"UL9))X1G\QB806ZUG:MZ+1O67M-]>H]S7VP:060<'WD*FP;C'R1*.LW +M)#H!&9!0-(:XG3(CN@)T$0/J!RBTC6886G_#RHX!_-()W2)@S/\`F$!O>3F( +MDS`$(#(/'RG:9.2?<)%OTR@1W_1$"X/:0)0T\D_NB+=9@`YW0+(G5B0G/YRX +M#XW3D:J<$NG?;W2U$$S!&^/KR@31+-0(D',82$:-I,X"=K26''Z[IP(=!=C; +M<_Y(IQ/L9C*)C9:!)SPE,8TS/;9/2:X#L9F5=(3@X``#'"-S8.7<*32UU*)R +M.R'2';MF,RHIG4R,$1&^=D_I`&,C*DIM+O:<H7:FNVV32&(UAA=.>4=4`50U +MC1,3/=,,.D`X_J*>OZB=R1G]%+RL5WODZ1W&,B$X<YIP9U[R=T[V&#J.V,(' +M-B()E72K%!Q:&N:8TYG?,JQ>75>_O*EY=NFI4RX@``G[*I1IR#@>YE2-_P"8 +M""94T@2[33,`R!A/2.LZS@#9-<5'U:HF2[8'X&%)IAH:(]/92KHC(VF>X128 +M$GU>R%V'`<\II.DP"H$]TOB?5VV2<9&J3'9-!+06DB3ND`YQ)B>#[JD+5!!^ +MIRDQVH@.<1[IIC9N/W2&",`DG<H:,20^03.^2F<0(#9^4X):`Z9B2<80@<DH +ML$YP#1!SRD#G\T=D,``:O@2?9)\AL''8]T$]Y1J4"P/+':FBH-+@<'/W4#7D +MR282<6C`,%VW*$D-)@&)'/*0.7G43P/9#K<1,C)W'*;?;[IL#DXW5#Z\:=1S +MW3/)U#)CL=@F$N<&EPR([H2TAK@?J@(%T8=]$Y>7-`D1*3,?F<)2):_!@>RJ +M&&,Q@;J#S`YP=ICV5BXKTS0TM;\E5?1,D'XE('J/$Q(@\!(U(;&H#ZIBT`3] +M0AC$%TJAR\E\"#'.R;4!L,X3`AN(XR4(C)@[J`G.)&`W`^$['2\@C(&(*9I@ +M3!/RG8UFF9W1`EV9D8V2EQ=O*8MGMVW3Y$@1/[H'UX2:X3!/W3``M^".4VSA +MJ]0]T!DB3`QLF>['.>R;TZ@0=^4PWD@F>`$#ZL1!@29[(FN(//P90$3,@0>" +MEIT^D9CD(B4.'((CWW4U")]IG95F07'2I:8`]6Y$*PZ:U!X=1:9C'9'J_P"K +M]%%;,8Z@USG"2I/*I_X@IJ)Q^%>\@2,3[\*G4]3L`EQ=/*O7H&HXP.9W56A7 +M=;W(JM]4;`JU52K&DP#W`0/!TC(R.>%(]TDDF0=T!,NF?NH!.^<@X3<;P2G& +M"#''=.W2=6K&,(&+L'`SW2&_"8DN@0!'LF9@QD#V0.#B0V9X1,:PYTY/NASP +M"DW?)_1!)`!@SGF4U,G3S]$1!+@&`D^PDH6983G"J'):3GYW2DS\(=68(&$1 +MP=OD%%*8$9R>$[SO'9,TPX#VYY0D^QR@7],$E/3U!TZL^R8`:9RDT9,X]T03 +MR"P;GC!W34R2X8^Z1([8Y2#@#Z.$4XG9VR0<3)SE)I!$$`9V'"0/](D"5`[7 +M'5+C!'LE4<7.`WX3&/,+@/NE4@B6SODH!;D3J/.R<[S((Y2&G5D3/,I#\\EV +M_(0+48F1":>=H/=.XX/J@H9&0#]^4#D[N)D\IB&D>K<G$#"$D$#;4B=+J(]4 +M0<!`G:M\"4AG,#'*%ID;\(VCTZ?N@8.`YCLBWR(E,6@-[IP"0`#GL$#M/JP? +MHB+BT1CV0AL-D;!*,R1\90'J!!).3ND"-67`-Y($H<EI$0$JA:'P!I;VF4$E +M4L:]S*1+F#\KR()'PHBWTZL0A!!/:/='Z=1AVH#F$#`RZ=S[(R=3VAVW.5&" +M-1D[(J=33K#`(<()*`B8,`9"=A@!TG[H9D?YI.R`$$K"?*F/9)KA,P$$^C3/ +M.#E$T`28P,*@Z>\3G[),P@88$"3^RD8)]_K*`F#\HTJ:@TEQ#),]LRE86]6X +MJM928YQ=@87J/X=?A_YY9<WU.2=@6[)&<L_5Q'2^@WE[6:VC;N(//^PNQM/P +MZJFS];8=`V^5[!TGPO:VM`-IT6-@1`"U&=+9Y<:`I<Y.G*Y99/G6^\$7MLXM +M;2+O=/TWP'U"X`=4HD-'?NOHJGT&E4?E@*OV_0*#:8_EA3WA[9/F^\\`WS&% +MS:9)VC"I6O@7JE1QFB6^T[+ZAJ]!HZ/RC[*J[H%!ACRQE/>+,LX\!L_PUJNM +M]=1V>T#O\KG_`!7X3J=(`<8=G;_9]U]']4MF6EN8;@+R[Q9:U>J=<IT?+AC3 +M^8+/OOX8V[WMYYT_PU=W-EY[:1B"29QNL.^M7VU=S'M(B0%](])Z)2I=)#?+ +M`;IB(7E/XM]&IVMX:E,0#N`KN6-8YW;SZBW2#G!*,["#./LB<'#,R)Y4=36U +MP(R#NHZA<[47$G/)2],2TP(2(Q+DS<M```[*J>F?3VSLDT""9,'L4+02=.T= +MDX.D$9^2@:63J:=^)3/#0,'/'LF<(,`3'ND[6!$R`-]T41_(,XA,T`MXP/[I +M9&(!`0C83"H<Y$'Z)$-!`)GVG`2>.8$'CLE3INU"/LIMJ8VG:W40,8F$VG!/ +M;:5.VVJ.W!RI_P"#TB"TR>W98]X[3]/E5(0[D8'"8@-(@Y[=LJ^RS#:8)$_! +MW41LW;_V5F<,OTV<4F:-0SGLB>9=C,;'LC?;5&Y:PP.0=_=1.I.#B-,'?LM2 +MQQN&4-Z`T$S*CJN)>&C')37))=C!43B0)'9:C(G!L8@@\(2T`P<1W3-,Y<,> +MQ2<Z`<[X506ML@$`0/H@IMR`?V0@SG(5[I5A5O*=>HQ]%C:-,N.MX;/L)W*@ +MID8D&$.!DC/:4[QB3./="#O\;2G_`%#@1.?OA$T&1/*!L3`XW`*<R&X_?"*$ +M@D$=_NEB),]DP(U29B$1AS2[,#W1#``D@\)VC&`@!DD*6UKU+>X;6HF',Y(! +M_0_*&T9;G&VR+&C^W=-J).)!/9-+L$\]R@?2"Z&R`=I2:1ORFGN8^B=OYL"> +M4!TIF6_*E:,R-Q^JB;F"7P/A2TR"<2"#NK$:-!O\H8_4H]/M^I0VU1IH-+G- +MGW"/73_QM^RNS:.[@SJ='SF51KENJ`(^JNWS0'&#,?,*C5B-QV2FD3C!P/NA +M<0'3(1.D849(Y60GYV"8@!^EY"9GYM]CLGJM(JG5AWNBFEL@!(#.0CI/%-^L +ML94'(=,(6[B-CW0(!NN#D)-_-$8&Z;!?,?5$&P/<Y]D06H:P`Z('=(G,QN4) +M(VREZ1!C94.8)G^Z(!I.K5D[H6@'(3@%K0`,*!G$:O44B!$SONAJ`.=$A(M: +MP01QO*H(8R4XTQM/U3AK74\[\A,2'1/`C`"&BALR"1&92(R8_P`D/]$$_HG: +MV&]OE`4;;DI1G?U!"<`:1$_5,P'.,J`OZN\)$M+3DI?TEO$]T,$[H";$3.X3 +MC?<;(3\Q]4MAC[RJ=$6P2-0W^Z%PTG<=MD3@0W>.Y*`[$%Q^94-$./5&=TY] +M6"YL<Y2HZ)/F:M,?TF,IFQH@$S\IM3@\DY'9&V`)P2HHQV/>43>8)RB#P7', +M`I,,`_XB<&4V(@G*$>DY!)E!(UKC@[)SO&J!W(0M#B<S":3QF-I5!-:[:-^R +M8[P8,)A)G@A(MG<[<HIW-!P0DT;`1!00`1,_*-HDF'8^Z&R>,Z0-]Y3M;!$P +MA=(P(3`N/930D='E9F>R3!Z)(0N)P)Y1ET",#LJ'@AHC:.Z=F6\Y]T+"Z2.% +M)1:[2=O9$%3:&-V$GDJS86M6XJMI,:7.<<>ZKTR3Z0)/<3*]#_"+PU4O+IMW +M49+`9`(/^2,Y9>LVZW\*_`=O2M67-S3#ZKA.1M^B]8Z+T^G;L#13`^%'X7Z> +M*5!C-,8[+H*-L)S"YY9;<9-\T-.V!`X/LK5&U!&6Y5FVH>D<*W3I:6KFZ2*= +MO;!KXC!5YM$%L$;?JCI4I,E6649XW4VU%-U$`:0%!7MQH/9:IH]A@J&K2$?L +MAIS'4^GBLTC.?9<S6\/4OXT/#?RG>%Z+7MY9$96==V6=7]E=LW%S->W%.V@! +M>7?BY8&O:/>`1&Y"]BZE2#&$'8;KS+\5*M)G3*PQLI+I9'@]]3%.I$[<*M5' +MI;DS[*U?5'/JN(V!RJ[W=FQV7:.J"7:I:<)Y,1@E.3#C.4.2=DL4XYVQ@X2@ +M%N9)]MD+I`PW"0=N8,G$(0Q(B-N\),#G#TR>PWE6;*SK5ZA#*9"V^G]'#-+J +MH),<KGY/+CCV]?Z?]'GYNIPPJ5K7J$0U7*72:P$.<#';9=*VVI,8T-:,(W4Q +M@:<+RY?J;>GU?'_Y>,_LYUG23H]69[*Q;],8QTP#P!V6Z*=,4<MR=D+:3=1V +M6+YK7JP_1>/'J,T68G#1",6L[;K1TM),`)F@%T8F%CWKK^S)\9K[2&@C'OW0 +M&W@"1[[\K7T^DN@`*&JP.PWZ*S-,O#BQZMOI=(;+NTJI6L0]Q!$'B.5N5:32 +M)(4%1AG`77'-YL_T\O<<]<=-)+LQ*IUNG5&9'J75>6W4<`_51.H!P@M77'S7 +MZ\?D_0XWF.3-N]H/I46DY#1F5TEQ;,)TN;LJ-S:-)D-A=\?)*\/D_27'IC:3 +MO@\PCHO<UXTG'(G=6*UK!D;J$L+"?3D"#(727;RW"X]ANG:ZAT1!V#0H7ZHS +MN.4;AR1`[$IMR&@B!WX59,R0(B$JC3H!@P=O=$X`#?[%,2"`V8[1B%$T$;&. +M$+7$"!,?LI'L+'%A,GF#,H'QJW0#,&`#)1&"/3(^J=I9`,F1M"$`$R#E`[3! +M@B2@$]RI-W9D]T,2^3A`GOU&3GW2:[)U`3\)/P9DIZ?Y/S$]C.R`Z8!$@?JI +MZ,3"B:`UL$`2I*>F>%J(T:+Z8I`&E/\`^)%YE/\`^'_^=/1T>4/[(_0FDVCN +MR&/CN=E1KM+GX`#5=O<./:?LJ=?6`!CVREYK2*N"&Y:-/=0`1O!5BYK&I3:S +M2T>6W3@;_*KDSF!\+*[`\`"<]R$CDYA.7&#(&4P=),`(A^Y`S^Z1)!G0/A,= +M]Q\)&#C5&$#P#Z2V9X",`!LM)'_2=T#7%K@1N<R41<XF9SQ*!C.F(,_"<-); +M._(2#AF1/]DYB=A@<(A-(TSRD6D`&##ML)R=+<_IRDYSB!,EHVRJI.#1I.#( +MRFCU2X9X[)$MU#&W"=S@1!;[94`2)&"B;@Q&1R2CMWTZ-4.=3#\'!)$'O]$S +MSK)+B23V0`1F0#_FB:8;MGB4TM!RG=AOI=/?*H9QSDDG=,/4,XSR44EID8CN +MFJ/UO+XR=XP$#[@;F#'T0N#0?E.UPTG)U<)G$8).5.@PTQ/Z)R<8.#PFF`3* +M?TDS.$#/`QZOHA/IR8^Z,D1!^Z9SN`90"T[%I_5(CG4$<&20<\?"0'HG(A`! +MCO/N$1+9].P3-!,G)^B,$;($((D&<;%-I([81,AN9G.R<]S'N@'$#)2:6@GD +M)CM&"=Y2TS)]\%-!.:0V3LG;H(]3@R!RF</1._&H)R&@X/V"`>#,2B;!SB`/ +MNF8-6J8QF$YTGL([H%)B"A8)SC")FF9)D>R1&"-`^Z!FZ2!,(V#!C9`S)C`" +MDIZ<D!`J>)&H`*:@T:B'\;94+&@G8#WV5FDT;8'U07NAV#[J]ITJ8U&HZ.Z^ +MCOPPZ"VRZ328&@$-$XB5X_\`@OTT777FU32U"G]>R^DO#EJVG;LP-EC*Z<L^ +M;IJ]+M]+0TC;W6@RB0Z>!W0VS0T",?"O-8'-Y*YTD*W;F8PK0IEPD;)K.E(R +MKK&%K0UH$$9*EK2O18(^%<HTY;@<(64X*LTQZ/[J-:1!DQ*"I1!G4"K(:/CV +M3$`^R&F?5I`">W"IW5'!ANZUJS`!)^%4N*;2,$PAIRW7*.JF6E>7?B%TFI>T +MJE!LC5B3E>S=3H-=3,#9>=>-*#VO<ZEN#V4MXX23EXZS\-R\ZGW&_LJ/B?P$ +M+&U%6WJ%[HV*ZSJMWX@H5GOI4'>4WDA8W4^MUG4]%VUTQDA<9Y?)/CO/'OJO +M-Z]I5H.TU&$9@X4-1@$P?ONO0NFVEEUB62))W6%XR\+W/3'&K2!=3<=X.%Z, +M?-+=4]+O3EG#T0>5+:TV.J,&K$[!.:,#U'`XA36+:0K!I#H_ISRM7+AZ,/!K +M*>SI^AVM(46QDE:1MVZ9)CYV6?TJHUE-K08+1F<J[4NB[!(@]E\O/?L_5^&8 +MS"2#K:1#0&^G$@;J!\<?HC+@3OOOVA`/S;Q!VE9D=./@BW@N.`AT@$S@QW1S +MQJ0%PU$`[JZ2TU(@$SOV3XU;X0GY3L.8_NK(S:(&<$X0`28F?JCI^IV`#/NI +M&-(,N(CNAPKU&X.3*K/;+B3^ZON#"X2H:M,3(:?E:QK&6*F*8`)X*%U,:O2, +MJT6:A(S\H"P`8'ZK<KE<5%],&2,=U!6IM..ZT7MEN,2H33!DQ,+4R<<O&RJE +ML)G2/B54NK=K3J#9G"V31+@8;!*KU:+7&'M,QN,+MCF\OD_3RL"M99]+8',E +M4Z]%S,1)/*Z!U,ZC#3'=05*#"TRPN]EVGD>#R?I9\8);D$@X]DM.T_<K3JVK +M"8S`56M;N!,"0NLRV\>?BN*N0-+3DGDJ,@&9;]U+5:1(((`P(49;%,N&\K3E +MK0?2#@(FMD3^Q0AI,G^Z)K=HDQP@0`/TX2.()!`*6-X..4BW$Y^VR`<$R?OE +M'#=>MS0?;9#_`%R<_=2>HC),#[HA4V@O`!&3B2K+:3J54L?^8;P0?V5=@+7X +M&_<*9H((F9[+2::-$GRADHI/<IJ!FBTYVY1K)PCO8#03$DP1'"IO+7#3'&X* +MNWAET-[[]U1J@9S@SRK5TKN.#&^V2FU`,DP>$50P)(!08#)].4`!P:9W2,'( +M@?"1;!QM"1T[&8X4"F>('LD73N,\)$2<"$@UL[[=@AH[@W!&4\@`2AF,-$=D +M0((/I*!1/'PGJ`#&_NAV`(^ONB@3,Q`RD*6F(S[%,(C!V1`@$1&4(.8T[?J@ +M)P&#P3PDZ"9@;X3$0X#(3;-R1WA`W<GOM"DHEC6G6P/!$"9$'OA"=)<3D3RD +M6>G5M&=^(0(PYT`&#R2F`@S(ENV)3P,D&1$(20?2#))A`[LM.WP.4M+3`#ON +MD/T30"[&)0.1,YVRFB&#YP$@")$_F2C3SE#1')P/CLG@;;)FQL#LG9&,F!C? +M=`G&#!,@]D,>WU3Z(&K,3"8?E(!S*!P($Y^=TX`(._<Y0G4($F-\I`$`'7(] +MR@=N''2GTX!.24IWGD=TL:B03E`^F'1V]TSH+AJP.4A&K#DQ'O\`=`FALP#C +MNC/I(@QVA1P6SZH@I\H$<@R[Z]TV8+2222D8!B/HGAH;((<>QP`@;40R`1ZA +MF0EN`(R,$IB"!NB:-I/&R!B"#N91-P"<D)1!C]$,'43DRBK8J6W_``KRO()N +M/,U"J''#8_+'SR@#G"WT;MU3]5".YW^45/5,;3V4T@F`AVX([>ZN6=)U6JUC +M#)<8WA4QJ#N-UT/@6W;5Z_:-J:2USQ/;<*I7M7X)>'/X/IE*K48-=4!Q/.P] +ME[#TVDQE!HD;!<GX2ITZ-A2T@"`/V746=4'2&F5QSRY<<8U:#"2(,1NM&UI2 +M`9,'=4^FM$!QC9:UM3!`@X66XEITVC:?96*;?Y1)Q'"&G3B".%(3(`;V4K41 +M'+H!*FHR8$Y]T-.D7.!*LTF!A$Y[*:5&01$HFM&G5^ZE=3!$\)FLTM@YE%0U +M&F/95+FG(GLK]8D^F8,*A>`G`A+1F7X]!,?*Y?JMHRO6ES!`.5T=_4+9!&.Z +MQ+BH"7$B(&%C*FF/UNWL'VIM/+:`X:0LNX_":UZ_T\MH-(J.&".Z@N:[W^)M +M)R`?[KU#\,NMT+6[;0K.&1&5Y/W+A=UWF&^GR?XZ\+=;_#SQ2VUNVO;2<[4U +MYF")_P!%V'2[=OB7PT0&@E[(F)S"]6_\9%C8=:\(_P`51:UU>V]0<W>,KRK\ +M`:NJU?:U#,9S\#"WGG,M91N;T\?\7]/N.D=<K65=NG0XP8W$[K*MWO-0.&8] +MEZG_`.(GI/\`_<MO6IL'\RG!('N5QW3^FM92:"UTC,%>F>7&8O3X?#Y//=AZ +M?4K-HB08]E>I:B(_0\*:VM<#TG'SA7&VA#@"V9]EY,LY:^]XO'<<=519J),Y +M/"-I>(EH6M;]-J.:!Y#B79P%J],\*W-=H?HT@;:@LSGIK/R8X3=KE1KW@Y2# +M:T?E.>5WMGX.`<#6=,C(6W;>%K%E-H-%KL025VQ\-KP^7_T?'A>.7DP9<$C0 +MUP=QA6Z'2NHU73Y+W%QDSRO6*/ARRI^H4F`]EHVUE;,9'EB`NV/@GVO'Y/\` +MUO\`\QY78^&.IU&RYND^ZL,\)W^DAQ:#[+U&E;T22)$=D?ETI(C$+7[.#SW_ +M`-3S?'EG_E&]TE^H'YW0N\)7;F>H@$GY7J-S3IM&1QM*K-8P.VW[J_LX)_\` +M4\SR^X\*7S#Z:<@'$*"MX:OV"32,[X7K;J3'#\L(76M$M]7V3]C%9_ZOE^O% +M;SI=W1,&@<;JE5H.#9#")]E[7==.MZH(-,&5F77A^S>Z/*;]E+X)\KMC_P"K +M_P#J/'GM(RX`905*(\LN*]4OO"-BYN*<$]ES_6/"#X)MS_\`A_V%F^'+X[X_ +M^CXLN+PX"XI2,CN5"6MC@SA=+?\`AJ^I./\`+)![2L6YLJM#4'TG-+=Y!_R4 +M]<HZ_N89\RLNK3(<9`(G_94+V!S",Z09VW5RX$R"9C8*.F*8.W$K<KAGC*SZ +MELTTY,0J-Q0(>0&Q[+<K,!(`[[J"K2!F``%N9O-Y/!*PJP+7Z2/RA,UWM"TK +MRW#Q``(6?6IAE2(D3DE=L<MO%Y/'<48@R<X1;'<QR$5%K#J#Z@;,^J#PA<`# +M`(`[K3D$:2,?:=U+2<`-R%&#)U'/8(@&F26^V#$%5!-<"[.2IJ)$ZR"H`&AH +M..>5-0@$`^^%4:M`32:0#$(M+O\`"5!39%,>MR+1_P!;E4W"OC,@M.,22>ZI +M5#L#B`K=WO+HDA4J@:79'ZK-:1O.O/W05`2X"!`'Z(X(,EP@CNHWY(P84.@N +M@'WW3$F(Y3R0[OREJ:701`Y0"Z0\&1!Q*41#6QMV3.,NW.F4@<9&=D#_`&WV +M*D86B3@8Q$84<B(V")D;DY0*,X_[(GY=)B-I":9($#Z;)YR1O"(?!`@2`>Z9 +MPTD2/LG!YS&WPD\!I<6@ELX*<*%HB=]L>Z?!+2XR(C'"9I/`YW31!COE`1]+ +M8WD\X2<"1Q`.R$EI@`00<E.8\LG(C]4"<T2#L/;)A*)',SOLF)$B),^R0(B? +MR^R!#`F3V3.$.)S]4Y,C`3#!GWD\H''S@#;NG<6N@1D[(2<D@C=,XP`<24"A +MP+FDG)@A24VDX+@,')/*!I!;O]43G"=P@3XDC;/="V2T2!ON4Y$@"4P,-Y^? +M9`S7=C(2+A,$[8,I2#J[>Q31Z<9`]T$A@S,8&$FY(`CZ(0!(V$[3.?A%)C?< +M(O18#?HG`+6->Z(?C[(=Q^B=Q,MD^PE$,[5P<#DIH)GDI5!#N/@)-'K$.F$! +M.;I9)<"(G!W48G5O$G8HW3DNV03!11D-T$`@&$@[88QN"DT"&S@E*/1C;LH@ +M00\P=OA&=R!C.)0T\&(W3D'5![JZ#N/!,(V.B21GN$+0TF"G.V=D!TX)U#E; +MGA&N+?KEO6C#'`[_``L*1O'T6ATUPIUF/R8,YPI87E]0>$KYMQTN@YCL.`./ +M@+LNBTW5-,X$;]UY5^"5S5O^ET0=F`"3/LO9NA6^BFS&?V7&SEQC7Z;2AH)X +M[+5M@T&.V%2M6P,<]U;HNR,@?59;BU(:TYGZI4A+O;E1.S$!3VPVD*?6DU)H +M&)4C&2-X2:T1Q,(I:,3[?"H<#2()F#RF(G`10#A,[TLD&(10.I>C5&V.RH7[ +MM+'9V"MW-7T?FC'?=9=\^=0=RH.8\27[:3RW(E4NG!UY(:/S<!0>--+:X(=R +MH/#W6:-D]_G/`U#!*\N>?K77'';,\16'\'U`U?ZAF"LZTZQ4M[X.UF0Y:/C? +MK-"ZJZZ+A`9!(^JXVR+ZO4`."9)7&WV:ZKM?%]Z>I^&JE*H20ZGM]%P'X:6M +M>RZQ7-++02/U"[#J=84^D>6#)+8CZ*CX2LC1I5*C6$N>2DWKUC4NG+?B]KO. +MJT61EC>WN5@]'Z#>73FZ:+HVD@KTR[\/_P`=U'^)JTR2T1!"UK#HK+>D`RFU +MH[0N^'AM_L]W_P!#'PX3'"<N(Z1X.>S2^X/P`%NT/"UK3A[J;3\C_1=2VTEA +M):.P3_P[BT""N^/AQG.GES_]'RY_63;]%MFL;I8W`X"M4[)M.G#6A:5M;9DE +M7&6[-.6B1NNDQD>7+S99=USKK5_F3"E%M4$`K;-!NK`1?PX+IC;E:<K:QJMF +MXM,#)0T;,S&X*WFVX.XD0B-NP"=@K-);6&VR.HN.(X4IL<2(@96KY0+@0%.R +MCZ0`?HJCGZE@7G/"B_@M.=,KI'T1,!JBJV[7$@A6)ISC[>IO^BCKVSRXZ9A= +M#Y!DB(X0U;<#>)A!S+J%5C9(.$#608(GE=)5M6.'TX5.I9-+L(;8E1C2[2!^ +MJ@N*`$P-^ZV+NPT9`YW55]!PG5'=-&V'5M&5'9:(&=EG]5Z!95J;@ZBP`C<! +M=$ZFW7@?9!68'$`-SLKTLRL>:]:\#TGS4HXGC_87-=7\)7EHPN:USF^R]IK6 +M\#+1GV52O9TJK-+F@@[@J62]QVQ_4YX_7@%6UK47N\QKA'>5#7T"F8&W=>S= +M?\,6EXPN--K701@;K@O$_@^ZM];Z#"?CLLWP[YCUX?K9>*XQ_J!=V&RJWE(. +M;@;[+4NK*O;^FJTMA4[ILM(VCCNL3<KKGK/';*:`TGV3M<`UX+=3G#!).$SP +M?,Q(0O'^&?HN[YUT%FG6(!$^Z,;0),(8(@9]RB.#Z096D$&QG)_93T`T/@F( +M&R@!AAD%2TCD>J!SA-)PTZ6D4P"[CN44L_Q_J5%3<\,`#G$!/KJ=W*^IN%>; +M%Q<X=O=4ZK6A\R3"MWC1F-]U2JD`ZHRLUI&2!(^JC<8GG^Z-T:/?Y0R`T&#* +M:0!+3S!CE,=,X,]T[FGG,IN<?6"H!D0`""C$%\'O!S"9TMXWY*$9@@GZ(IW` +M`;_*3?I'$)-TDAIU1.1,)V!@>700R<2J@VMP,GV[)%PWD`QLE(V$I.;F"443 +M1C3(E#4WXSPGW.!OB4+L`0B':1_LIY'F#\H'OE`W?:/=.!P<\H=E4TS$G*6) +MTB3!W)0U`9B1&Z<!LS(C_"$#X$C8>R3_`$`01!V*$@%WM[2A($3!440+8DP> +M_P`)-]7'LFW$@@$<).:X$#(,3"(<Q`,)C@R3LD1D28"9X$;P@0@-C5&K>$3= +MI]D.B&CU;IZ8/.?9%.W2'1$F.4Y'9XD\H""`08![RA`)[0/=!+H`HZB]KB3^ +M4`RFQIB!\%#"<?E`+C/(*0.T3`+H]Y1:<8.$&[MOH"GWF(&(D(:2`L-/3$.D +MYE"3G(VRG8)S*C=^;V"`B`8[\IM()X)2.`3,?W3%I:[5)&-R@,8;G890.:"[ +M`]TXUQC>3E-SEKI*`FQHQCB>R>(&#N4)V`[CE.X>GCY"!VCU2,]D[@#.\I@) +M`EQ(`[IVF!/*(36_U"!",@:-6!/"C:7-.F)&$[LY&P/*`P&^V=RM"P8YSF@3 +M/8+.8'<NTQ^JT.CG_P!2UI."X82CZ5_`*Q90Z!0)`EPF3]%Z]8M](`_1>7_@ +MY58WHMLT<,'[!>G=/K#2#.ZY95QQC2HXW^ZN4F8&RIT'<\*U3<(X6'18IM$[ +M^RLT0`/T56F9((^JMTHP9V14S8#"XCZ*"I5/F1SW4I&(!4+J<&82K$U"H8,G +M,IJK_>4-,:<G)2JQ'*""Y<2/U5&\`@DX/"N5G2=\CLJ%T0>0%#3A_'#'AP<) +MB<X7"=>N"2&,)'<SLO5O$5@RO0=.>5YSXDZ.ZD7/:V2"N.?B]NFL<],FI;U/ +MX)I+IGNJ@K,MGR-QE3BI</\`Y.DG^RT_#_ANO>W#7U&G3,Y7*>'*_&O:`Z1; +M7?5*S1I(9O\`*[OH_2&6UJT:1,=E>Z#T2C96[0&B5IOIZ6B&X7HP\4Q8N5K/ +M99TV@@`;3LH*U%C7:8"TVTGF1D(769).)*ZQBLKR#'ID\J7R/3^671@+4IV9 +MQNK%*P<2"6R5H8M&T=@Z4?\`#/#IC!X"Z>\\L'LI!T\NC"I(YW^#($[J6C +M;3(^JZ.GTX!OY0C;TYK0(:$-.=_@L;;H76T#9=2;`%L`2H*G3`'9"&G/?PX: +MV0W"C-/3,#]UT3NG']5!4Z:X@]BJ:8+J<_EYW1A@B#QPM&K8.!(TE!_!G)VQ +ME$9KZ0&PW0NH-+<P!W5^I0]6)P@J48;M'LJC/K46Z?3RJOD>K:%JBF9(C=15 +MJ0DGE!F/HASH.QY*AK6D[#9:3:<.)_=1U</CCE$8%?I_J=$2JS[)[28;(!70 +MUJ37"0`JU1C6B9E7;.F!<4R`0YIVV*HUJ#@[6`8[!=%<V[*GJPJEQ;`43!QV +M*2&W.UVDN`@]U5N*`J>E[9"V:E"23'W52K3@D!NRHX[Q'X9MKT.+&!K_`&Y7 +MGWB?PO<V)<X,);G9>TU6%C28A9E[:T;MQ:^#\J\7MO#RY8=/G6_MWTZQU@@[ +M0JO'8KU[QQX.I50^M;MAR\RZSTRXL:[A49!G'LM7'4W&YY)E6<W!B)([A/,N +MV&G9/4`D3QOW2C.28696M'@@',X[*6W!U`#G*!L!HQ[94M`-<2X"(*J::--\ +M4P"V?<!%K'^`_8(:#:?E-U.@QME'II?X_P!U/:&J"Y]+BT&`<$0J56)G<<1* +MMW3?ZI$\A57B=GP)R>RM`U6T&V;'MJEU5SB',TX`[RH!^;=$\^K!!08=.8(X +M[J!-;_U2.R$M<)D0>Z=I@YPED`D.SW)0"]I(DB?JK+`*-E4(>TOK```;CNJY +M+B28VY3.RV!QPH&J/U2`C,'X28<29^Z?7F0<'NJ#IR':Q,QC.R%P).`#/ +M,H28.TH@2'9.-E#9Z>VYE)XW!;/:$MAV0ZR3/?94/Q[)#3W^H0Y<#`VWA,"# +M+H(*`G279PEI,;[YQE,2!DRBD:9S\!`+MH/Z(28<"6Z@/U1-TCN/=-5<=69A +M-*$'?LB)<,SN(3.(@P)0D@`X/RH"DY,<)'CW*8G,?=(.,Q&P0.)C3LG)(,-. +M=Y".JRFV@VHVL'$[MY"BU:=\]E=!W%SO<C<I,&#,^T'E,'N:)82)WSNGU8D? +MHH&,9$9E,Z!RG+R#IS'N83AP@;#W"!-D-Y^919T%QVVSRF!&Z(N;Y<;'5R@$ +M$`R/T1``N,3!V3M>TM(."$@0?A`+H!@S\H2'''[HR3IC!^0F(@F?M*H;3F2Z +M`4OS2(!]TX(CB1PD`.,=RH%`$22DV(Y/LE@G/T3C3&((F,HAVB"1]$M#MHG2 +M<PFV(`'W3@D2/\7NBGDHBXEA:W8J-Q),$B>(1@P,X]Y0)N/G96^G/+:@)G&% +M4P3),@^ZFH%K8,Q"#Z&_!#K!J=.I4M660-U[3T>L'4FS\[KYE_`GJM*C>>2Y +MP&H[DKZ&Z-=--%I:<'LN.3EU77V]00.)X4VO.)PLBQN6N$3^JTK7U#<P?=9L +M:B_;N)*NT2-,;*C1@*Y2(,2BI2Z,)4W3(*9S03C*8PTS$2BI'1&^.ZBK/$0A +M?&C_`#4);//V2@*ASA0NIR=1W5P4H;LF%'!(4T,R\I![(E<]U?IU.H3S*ZNZ +M8!L#*RZU#SGD?LJECDK+P_1_BB[2")76=*Z73HT!I8!"NVG3PUH<0M&WM]+` +M%I-*3+8Z1B$S[<G@+5\K`'9*I18UA)5TK,%J`)`"E9:@P3"FJUJ5-N7"/E9_ +M4.M6U!I'F-GY6+G(U,;6C3HTPV3IPG#Z+($@#W7*7OBBBUITU6_=8=YXO9KT +MBKGB2N67GDZ=,?%:]&JWM%HPYJB'4:6K\X`7F%UXO#&F:F!S*JT?&]`U-)JM +M!^5SOGKI/"]=;U&F'?F&R1ZBT\[+SFS\34*K`?-!GW5ZVZY3?4TBJ%)Y:U^U +M'=4^IM$Y4M._:\#(*Y&A>^9EKMU8%RYH_,M3R5+XXZS^)I.;^Z<5J+O3@2N7 +MI7;MR25)_%/U#2\_"W/-6?VG2>73?S]$#K)AF`/HL2EU"HSG;E6:/5SR2MSS +M?EB^);K=/;I,#/95:UA(,"`K5/J5-[<D%6:=U1>W,`+I/)*YWQU@/LBV7053 +MN:'(;E=:ZE1>"1"K5NGTG">%N65BXZ<DZWAIE5JM$3!P%TUS8$$@`1*HU;`@ +MDQNJS8Q:E!@;@'OV5"XI>HY,!;=:W<#$3"JU[:0=059L8D!KLY"CN*;7D#A: +M56VD$8^57\HM.1*(RZ]!H!`;"H5:$/)B%NW%$ETZ57N:`TR1*K+G[ND"TF-E +MEUK5S27[+JW6[<N(A4KVW#@0UL2J.9K4V/I$/R2N4\6^%;?J+7/@:O;_`+KO +M+BV:#D2JE:BSZ+4RLZ37U\\>).B5;"Z>W3(G!A8P8`2"(CB%[_XEZ%:7])S0 +MP!W=>7>,?"E6SJN?2G3RKZR\QVQ\F^*Y-K00!.VZFI?F&<IKBD*3S3$R.4=$ +MC!,++HOT0/*$X/RBTCO^J:B!Y0D@(]+?\014%T&C())[*I4(U06P1A7K@`O, +MP>-U4>X$1@-X'*"#3/J@X0.QQ,J4O@$MVV(0.#0!ZM]S*B(R!$@E"8(C@*1[ +MB7N>3E,6^D.<TP=O=!&WW._NGJ=VDM`2[XF$CF)CX4-!!C`._='2@RV(Q,RF +M=$3&W"9F&QGZ\*FC@$?U$GV2<8Q()*4AVY2T@$,@^Y0-)!S'NDT-G'.R*8<9 +M2&F`#@\J&@M`,F4QPX@[*2&[@?5,6^@F!.T*P1N.<9E$T`,F8C=#IAW^PC:& +MQ`P.5%)@`IZI;OM.4!GC3D=D6`US8,[C*3P'8;P%0VG`C'LF+27]D36X#G3G +MDIBX!T@@>Z`8&"4T0=_UW1%H.9)!0N@$_M*@:8WRGUY@?J4MX'*3&M[Q_=#1 +M$G3,QW1%Q&<Q\I@T;;$^Z3`Z8,GX0T3A@8X[ICW('Q*DTAV=1S[IJC0(TN(^ +MJIH(/$@)'8NW]TX``R0$HD&<B>ZAHFX.-N?=.TY'LD1O'";\L'<E4&(.Z;)D +M$(1)!S]TH.H;GW"&CD`9V1..8'VWE,&EQWCY38D0=T!8+0`(*:/3L8Y1.:9R +M1MRF`@YGW(4".!L430]L5`"T;C";?Y&Z1F2V20$31.C5(3.,-`2`=&^Z3PW2 +M,S[*KHPTC(A24JFDZH!`X,J(F#QA.-LF1[%#3;\+=2J=.ZC2K4GQ!V[+Z2_# +MOQ'1O>ETWBL"Z,B>?NOE<&#.K]5U7@OQ;>='J-#3%/V)/]USSQ^Q+CM]8]+Z +MB-7YC]UU/2:XJ-!#XYW7A7@?QG;=0H-+ZH;4Y;,2?NO1/#O7FD@&JT_!7&\, +MZL[>E47M#<E6:-1O*Y.AUIAAKB!*T;?J+7'+@1\J;5T+7MYA!7JR-A[K/H7` +M<?S?53ZQO*JI6^KW"GI4S@`_HH6.;N/NIJ=3L1CE6"4-#1.?A,UYIG5@SB"$ +M+W@'?=0U:K3/L@JW>7$CE*RMM3M1PC#=1WGV5RR8`?=6(L4[66`A05'LIDR1 +MA6ZUS3I4"=0PN"\:^(_X?4VD<[83+.2+CCMTU[U:WH-)-1N/=<OXB\;VU&D6 +M4WR1OE>:]>\0]3JEVESH/RL!]:[N'ES]><%>3/RVN^/CCM.K>.JKI#7&/E<C +MU[Q;?.)<"\@^_P#JH6]+KOD^HS&\JQ0Z`^JPAU,GY"QWVZS4857Q5?UC'K`F +M)@PJUQU#J3G"H*CBWVE;=;PHYM:(.G?'?[+8Z5T6EH%-S,C@C">L=/:3IA]) +M=7O:!;5)SC.ZSO$/2KRE4-6DXP.R[K_@[:%0.:W3_97*G2V5Z&DM!/=)-,^U +MEW'GO1+R^H/%-Y,#NM^EU&XIM\S45?J=":VM(;'O""KTPAT:#'"Q8U[;;'AS +MKS]3653@>ZZZROJ==DM(7GM&P?3:'#$+6Z76K4:@:7'"2V+K;M#5WAREIO?/ +ML%C65Q,:C'NM>@6%HV^JU*FA.JNU0)1M>X['9`Z"TY^B!WY/VRM,Z6F5W-Q) +M@X4S+EXR'&5EE\#>5(VIZ<.A39ILTNIU6`2?U5ZWZN',+7+FJ;R2<IV/(Q*W +M,[&,L)75"]HU!N/?*E#:-5F'#X7)&X<UI+7J2VZI4IF!4)"ZX^9ROA=#=6-/ +MR]0`^RS;FQS$?9%;=8U,`<<*V+RG5;!+9]UWQ\LKCEX[LBT&`9E4;FV>! +M,976NI4ZC<*C=V6#NNDRCE<7*.:0XR,J"Y@;-"W[BQ.LDM69=6NX`"TSID5Y +MF(4+V@L@MB5JOM"&203"IU:0!C9&6'?48.V%0N;.6X"WZX(&P@\JG6AWHB6K +M6T<M<T"'D`'[RLKJW3_XBD]I8#/LNON[7/RJ-S2TMTZ?N%>D[>&>-^@5:-R: +ME*GCF%RX9I?!!@<+WCQ'TUMQ:U&.`)(PO)O%/1JEE<NFG@[0MV;YCKX\_E5* +M#6FDTZ@/NBTM_P`8_5-0I12`!'V1^6>X^RY:CLJ.KUJ;*U*G5=396:&5`#AP +MD'/V_14GP#`D_P":M7@;JF/]54J#B=\[JT`2UI`G_)';5*#!4%>FY^K8M,05 +M&R`PB.VR$.]4Q*E@,TF/>UM$N<7;`[J*."XHW!NJ0"UO!E"8(`.4`#Y^DIL" +M)._;*.(.ES3(.W9,6MWDQ\H:"[V)'PD08TS(Y3@`S&!W"1`+<X*0"R2[)/NB +MDAPW3M#=^R48VGX0`?9R=X#<@G/&Z=S00(&)A._3P#@(!#3IDN$?*>2)D[;) +M@V#G>82!D<_912!@Y.`G=$C.`F($@$004[P)W]T`@2[*=QQ)^GRGB`29^(W3 +M:0002<?1`Q@QI^D).!F>/V3F0()(0N_,1G/'=`+B8B1',)LGW[)W?_<?IV2F +M'#)309H=].R=I=M.#E.=.G=Q[(0V02#LBGU.+B<92$@?(W2S`D1"8S.#QL$! +ML+IQWV3DQ$'9"P@-S)^41`P=39.,<(@9DR7#.8E2-UAD84;0-S@#V3M,#)D` +MH#+O2&D9]E&XSB-S]D;3#?S2#&$X8"T\CN@`.],N'W3M_/+A',IRTR`8&R8, +MW`+23PKHV>'9CG.R$.,SCX"-K8P3OCE!'IG[[J`B1(C8[2G$EI`'ND9D;93& +M9S$H'GU&!`A,XNS`PC:"3$A`X<M."J!U9^46LZHC9!._^:(&<#/N5)`+7'5L +M"3NC)`@X^J%\AP(B-L=D37<P,"/9-`B_@@83^81$8/*9NH@_?=-,CO[`HK3Z +M9U2ZLG--*L\'V)7;>#/Q%NK2X:+EY<WN2??W7F[2Z03@GA2,G@F#NLW"9=KM +M],=#\?6%^&!MP&NC8F%V?1>LFI3:X5<?*^0+2]JT'!U.J]KA/*[3PQ^)'4.G +MT/*J.+QP7%<KX[&;C^'U3:]9VE^?E:_3NK-JL$/E?,O2?Q4\VMIJ@M;R05W_ +M`(8\=V):T^<,C8X7/5G998]OHWI(&=E,V[;OK`(W"\UH>.>G>2)KM/O*+_SI +M;&`VN"1C&?[)N4>B5[T-F'?""A<^>,.,''RN/Z1U5_4BT,G2>2NOZ=3;2I#6 +MMR;9VNL>6'\TC]D]UU"G:T2XN&%5N:K:=-Q)^ZX[Q7U-Y8ZFUT`*97U:DVF\ +M4>,0POITWKC']5=?57>8=S*C?:/NJ^27%:%ET.'MAL^Z\F6[7IQD@;>QIW#- +M6G)Y5BUZ'1G\@QG9;G3^G!M/0=BM.C9L:P`"/E6+_P`<]2Z12`/IB.5<M.FL +M;_\`HP/HM@46@&0(_=)K6MSP4Z)&1<=+80?2"=YA5Z73-+I#1[0%T+FA^^_9 +M'3MVZ.,)VO3FZUI(+7MDA/0H:29&!PN@KV;8,#V*A;9@G9+"5AU+9K7!V,;J +M,VS702``#PMNXLQH=ME56VWKF)E9K49-Q:CRS`_U06-LUY$B2MPV8>'$]E5M +M[44JF<05&H@T.:T@#A:/3ZCO*#3NBI6S2Z2%*VV,^D?"B[2M,C8?=([R%+3I +MP())"*E193:0R0)P.RK*HYA)QO\`LH7/(,*[59I$JI787.V1=&I5#\(C5]4! +M0GTDD[A1O=I((,PIH6WU!I$#=0.<"R1(^%%K+G`26I`D:H)DY24T-]9S8TJ> +MC=O8R0X[\*EL3G!4-2L6OC/PM)9MTEEU8C#C';*U[:_H5J8@B8R9W7$4WDLP +M[Y4E"[J4LASH^5TQ\ECCEXY7;U&4ZK2&@+.N[`#(;NLNSZN6.ASX[Y6O;]1I +M7#1Z@O3CY97GR\5C(N:)8XM((E9EQ;.+R<P5UC[9E:7`A4;RP@#&/E=Y7#+% +MRMU0=I/99E9NA\1GA=1>VS@8`$+,OK?09Y"U&+-,>H/3J+=/UE4KVF'QZ<E: +M-U3<7%NK2!^J@K,I@8=!"LX1SG4K,E\'DRN;\4])IW=B6%@<Z-NR[CJ%'4#I +M[\+*N;4#&_<]U9=7;.GD%3P_58\M;L#W3?\``:W;]5Z?4Z30>\N(R>Z;_@]O +MV"W_`!=?W*\#NZD/APSR=U4JOAT@8XY4U?\`.2,859PAW8>Y7.NVR+H.TB,% +M,7##HC'>0FQ$B$S@`T=SQMA0V,U6;-!@C8H?,TD.8=MI0%H`F9A`(,AT^R"5 +M]8OJE[R2YYDDF24.L3JSGNA@:9!Q/^PE&(S!W0V(5#N`2"93O>#F<GD(/3R= +MT.`"V-C\0AM*7@MD[[$RG;4&PD:0HP`>8]O9+$S.P022,DG!2#O1$X''NHY` +M[YV2:(S.>Z`@0'0-MLIVN9D\;*,@S,XC9-`!DN@'A%'Z9U<#$HG.86CG/*BW +M><E'JW`.3RB;.'-V=(/()V17#6MKEK*S*FQU-F-O<!009,0$HD';Y)1=I:=1 +MC7`U`'CELD<>R'6W0TM.1PHL@`0(&Y3`8,9A#:1SFAN\CO*4LC\V3R@CD8"1 +M&<X@("V$1CV*)IQ!A1Q)DGA(-,?JIHV,/;J.8!3ES"Z3IGVQ"`M(WV]D)C)G +MX"NC:1I;F#PD).9;@[J(Z@8//9.<`'ME!(UP@B`>9*(P&@%TQNHH@9VYRDT2 +M,J&TNKT_F&/T14:C09G'90`&,?;NFC.VWNJ;62[UR#(D)FS&#C]E"&.B8._& +M82(AOPH;3D`#?9"/SQ,R@9L3,':"A&"8P=O=4VL?TB=C[)B?4,S.)4+2YVD@ +MP!LE,;*&UAI$!TB/=`XC!^ZB'IP23W3.RT#GE71M)N![)X'$Y*A`(?F8GNG! +M(GV]T5,WL.$F<-])A0DGO\P48,N:9G"(E#23,_24X+2!`CVC"BUG,DMQPFU8 +MR0"-LY1=IZ<9''S!2:2)$P.Q4<@/W,<Y3:SH&=_=#:>3K&))X3AQ)D;;C*AI +MN(V.0B$ZMX]DT;3-J.;D3@YA7+?J%RT'2\YB<K.:2V"#F.Z*B20-.2EY-MBA +MU;J#RUIN:AT["=EZ3^%5AU7J-VRK4<[R1./NN9_#SPA5OZK:U8$L]QNOH7\. +M^@LLZ%.*8@#Z+%D[9S\GR.O\%]*9:V;!O`75@-#!(@0J73J8I4?8+.\3=6;; +M,--A`G`6,LM,XQ7\5=6;1I%C=SV*X[1<WUQ.8[*6GYW4+HO<XQVA;=E092I; +M+R9WV[>G&:!TKIS*(!?$K5H46X`&%%2:YYX4]'7OL>5C;K(MT6L`G2G>0'"% +M$R3N8Y1!CC`F5-[;D.XZA&`0F;3^P1BF=)[J;R@Y@/[J=KPA\OG,*Q1;!C>$ +M@SB"/HC8P$AORKK25)I:3D`=_9(6[=)@#Z)B0-A/"-KQMA:E9TJ5:68CY4#[ +M?2"8RM%PE^P3:0Z,*5J*`I13_=4G4?YA@8'=;GDRT[2JXMP2#A9UPUM4MZ`@ +M$_JIJ5-IF0K#J):.WU0-9$08/92B(,=JP,!3-I_RSW4]&F3EQ^JE%.7#N4D& +M959B'#!Q"J7-*#$;=EM5J30W;*HUZ4O@<;H,FNQT$D0J[R)C<[+3NZ3B-L+, +MK-WWQRHL!4R#$9[)A4+1,92;)$&$&\JE-4<">Q]TWE!XF2/JD]P!@CZH758: +M2W*=()K0UF#,IY;$"%!YH&"=NZ'S@';_`$2&DSAWW1T*]2B):2(XE1MJ@GF4 +M;(>V"5N,6-CIO6"QH8]Q$]EN4;FE7HX>,KAZC8!(,?W3V74*U$^EQ@<%=</) +M<7'/QRNMNK9NIVD2LN_M"701]5-TKJ].M#:KOKW6MY5*NS4UPSLO5AY)D\F? +MCL<1?VV@06K(J4'/J3)#5VW4["23I,'E8E]9.`)&'+MVXN<J4X>03C*KW%LW +M20&_5:5S;Z'Z@JM5P+M)V"#--"F#!R4WD4NQ6LRC1+`2""47D4?=.%?)%<D/ +M,#.T`JN]LNQL=@58?!=),2>56?O.XXRH])J@@$.TRWLHV@@',GA&]QYR.4SO +MRDR,<(R"1)`W^4B(V!2G>&IB3JVX[HIW:-1`.`<80.B9!(([IYDP2)[IB2)Q +M]D#.=/(^Z)H@:L'ZH3&G#3O\)<B<E`39:,Y]QPG#1#G2,8B<E"UY`<8$GLB9 +MP"WXA`L-,&9&$],-Y=$<QND0X$AS((.QX38@J@2#N)W1-:-.<#ND#C;"=VG2 +M1[;J`,D\!(F6$&2!P4X+9&K,_1"XM#L9212@=I([)J@.K?YY2$1L?ND70TB, +M)$,0W`)VQA,&[P41(G/ZI-B,(I@0`1PGDG)^$SC!$<]D\CB90.T'8'<[(23_ +M`$[%/J[DQNGQO*!G<9"3M)$_W2!@2'1W"0@\?K"!:6YQ$\)I@<_*)Q]&YC@' +M9,=(=D?J@1$B!GNF:!IWA.(!F<)0W,2F@B!&9RA!&F#PC^<I/T%H`$)H,PP? +M?E."9W28!`$P">R8B#G]$"=J(_U3M$X;B>$YD`MF0=QW3-@C+9(Y0%I;K)VC +M8=T-0R[_`%3AH<[N!PF>-),B/8H'8).9,(!IF/;!)1$ZL>R$B,<]T#@0P'?@ +MI@9/Z).,-B4FG&V_*!P`1C/LD-0!]1CV3,.(`^,HFF),8^4#C5N/L$[9/IC, +MY(2$@8Q^J*1(:1]$"(],0<<)J>F-DY@M$?ND(F0J&/I<5+3(,3D$IG!I!.QV +MA.&P-ON4"(!$#E=A^'7AQW4;MKZC)8TA8/0.FOO[UC`PP2O>?PZ\/FTM6`L' +MRLWIG+/UZ=#X.Z*RA2IT*;,-'*]+Z);MH4`-`"R?#5@U@!(B-PNB>6TZ>-EB +MN<YY1=5Z@*%%P:1C<RN)ZC5J]1O8W"TO$UWG0WE0])HAPUN$GW7#.N^$VNV- +M'RJ0B)A7K>F7#U)K2F2-ONKU"G!CLO/>7IQA6S`QHA3&F0"4@`'2<*1[FAN( +M6:Z2$P"6XP5,T#&%`Q[2_)_56&'MNIMK22FUNG_52M'HQRH&$ZO2K5`#3_=6 +M4T`,,0!",LT@3^BD$.F,)G./*K*%T\H28B``GJG_`*E&7`[S`02XB)1-B9C" +MB8X1,DX1TG09/*FQ/'I@#Y3^6,N)@CV3-)(D(Z?YC^J*!](O?`0U:`;D?16& +M-&8'Z)ZE)KP`X2.45'08W1&".Y5@4QH,)4F'4('W4^D:)'*1*I5*0!DSE5*U +M(:C&Q6C6:!.)A5JC6S);E18S*U"096?=6S1_3!6[7``^50K,#R3C"G2L-]') +M)&`@\HP?9;#K=A&!@JLZD!(`0K(?3)!&WNJ]1C]/I(^@6S5H`B`,JM_#:21^ +MB:1EO;IG!*A#'ZCO'*TW6WJ,A)M!H$&$TNU&DPG?CW5BG3@;[J846L),<HF: +M8$Q\*LVH'M.QS`55WI<9'U6D8C>)5:O2#G;;K4K"FUY:[4Q\%;/1.LN8[RWN +MU`+*=;$B<J&M1<W:<96ION,927MZ'9W%"\H2""85#JMB8)CX7,]%ZL^V>&/< +M1_OX7765[3O*(@CW*]/B\ORO+Y/%KIR74K0LEQ'ZK%K6O\S6Z3"[OK/3@6DM +MV7-=4M2*1TSCL%ZIR\MX9#7M`B?U2\QO<?=,*)Y!E/Y/S]TTO#Y%K-)F71]5 +M6>0<`!6*YEQ;`&..56>1Q"E>H+@2/8)/!D2-TSMA)QV2(F'$X]D-&<,X[(2) +M))&41`'9"X]T#$&9@&=BD9`B"2$PSMQPB<US1+AID2)Y1`$&1.Z1!X!!/&R= +MND9<X^R8D2/[HIP)]61"(2.#'>4)@#_1%3=+80/+MR23WE-LTZ@DZ8&04TX@ +ME$.!Z9S!2W[I9#1.4I+M.?:.Z`?3S,<)`$DX=/`2AP<<X2/<[#;**>J^GJ;H +MU;>K.Y00TGL=DY!C4[Z2D3)D'/NA#`@..GM&R0)`^>R=I+<S![)R22),H&@` +M3E-B!E.23DY]TG0.?H@89=CZ!/.,9[I@Z,#*0)$^Z+H[-B8D]PD<MS'=-,@1 +M]@G;OB"B%@'\T=DQ[!%D[QGB4P_(80-&8.",(C@;`I-D@`&9X2&\0#V*!MAE +M-N,\\HX)'!.^R$N&G;/[(:.&XX,?JF(,SLD)&0TY"0$MQQNH:.#B(&4BT<$' +MW3@B-Y`V"0#]<M$&,C*!`#<\]D\M%0.C4`>4T>F"W=)L!ID?14/=.I.JEU*G +MH:=FZIA1N]@B#26ET8:)WV0F-!Q]5`Y!<=1&!RF&Y@>^Z0(E.8!$85":V3D' +M"<`:<#;=+4T99(/)*=H$=^Z!"1$#*<09F?HD1MRG='(DSW0T8>SI]D]-OJ@D +M;[)@,;F?E&(&^_LBB.6P>58M[>I7<UDD@;*!NDD9,_J5VGX?]#JWMPTFF0T' +ME&;Q'5_A/X:T-;6JLDD"%[?X8Z;%`'1"Q/`_164[:FP#``7H/3:#*-'3V6<J +MXR;NTEK1--L]O95.LWS:--T.B%-?W+*-)V8A<AU2Z?=7&ACC!*Y99:=,<=GH +MNJ7=QK<XD$KH>F6^&B%3Z):!K!A;MM3T`8^<KS97;TX8Z3T:(:,2`IF-QG9" +MT@-P<!4NJ7].WIDS"Q:[1+U"Z;2!,C"R:O7*4D!T%9?5;]URYS:<Y[*G1Z/7 +MN8<7EL]ESN[>'3<C:/6FR2Q\QV5RRZR'D`N+21W6=:>'SI:,GW5D=%J-R&N! +M"OK4]HWK6[-5FH'Z`JRR^+?S#3[K!L35M7!KP8^%J4GT[AHV"FMK&A0O&N/Y +ME-4K!W]06-68^B8&J!V34;PZH.RSNSMJS?34>Z7%`V=63`4=&J'"094K3Z@1 +M&5N7;-@R('I&ZDH@ALB$PRTG]$3()&(5TSM-3P8S"GIM`,A1,(.5*#VQW32[ +M6*8!@2BTMG?.TJ&B1JVE66%IW"!1`P[[(RW!F4@0`)&/E-J&<H(J[/JH'4X^ +MJLN+2TF=N`JU1P#8,E18JW32-C*KADF"%;())2;2C?=.U4JC-(5=U*72X0M% +M]+42!.%%5HC/9$9M6F&["0JM5H`)G*T+EI$P-N2J5<8/?E39I1JN]6X5.ZK% +MA)/"N7`QJB#^ZS+MI<W)(!X4BZ05>IX(:[([JG5ZH8!UPH;\-9(:!/*R+IQ) +M@'*9$TZ&WZDW5)=,JT.HTW-`7$UKEU/)<<=E2NNN/I,($^V84F5B7';T,WK# +MC4/;*FIUJ+VP0"?E>3?^9;IE3,Z?=:?2O&#&U`*U32??*U,_\2^*NZOZ/]30 +M1_=6>@=0=0KBF2L;IO7;6ZIC2Z9&_P#L*=[VEVMI'>97693+IQN/RO1[6LV[ +MMPT1)&95'J=DT,((^BQO"G4SK:U[L]UV+A1N+4.!X7J\7DWQ7C\OCTXBK9-% +M0Y_1-_!-[_HNCJ6)+S#"A_@3_@*].W#3X'N-RZ8G"KDP2"#&RL5\F&S([*"I +MZJ8@F1B%-O2A._<#W2.H#V3NB3N1&2FJ.);OM$?"J<!P9@_KNF<"<[9A.6Q@ +MQ*8YQLHIO[[IG;03/U2(W&>R:">3\J!#,G*7S(A-M[)\=\<D(',1DR`8R433 +MG]X*`C)!G='@;<JAIGCZ%)P'"1'SC=$/RSNG8$D=\#(3">Z=P:!D^^$HD2=O +MV0)F#R)3NB,QGNDX``9'U"1'I,<(IA^4$B>Z9\``C]D_],S!A*0/^H>R`(SB +M<>R=@)G.Z3@``Z1GA,#/$(%IC'"49!V^4XR)/"3))$9[94"(R2(3/V_=&0#. +M-]\JUTQ_3J=.Y%^RJ\NI$4?+,0^1!/M$JBG!C<=HW3"=6#D(FDZI`GZIRZ6P +M2/D;H$"TN`<(2<,P)^$((@#;Y*=TD8?C_P"Y`\C3_ACLG:X@[S*;$$S@=RFU +M9E`1)X.=D)!C"67&>P3`8,9*!`^J28'<<)R0-G<]LIB!/")C27`-&78B$"&/ +M43@IP#!,'2>3RF<V)U-@_97.FCS[6K;%S6@`U6$[D@9'U'[(*U3`$['OA"<X +MQE.-,R,SRD[3J@;(`,C_`"3MB/5^Z3@#!VA,&R#E#9`Z3@;B-DWJGG"+9I2_ +MJS]4`QB3RB9&9F/V1%HD!IG*<-CT.G4TY:$"IZ=>DR6]P8,IB0#I&8[%.6Z9 +M;I(/,H?S/COR25%$QQ+H(1F3&G[E-0\LEQ<7#'')4]M3+W-`R51?\.]/?>7; +M`&D@D?NO>_PS\-MHVE*:?J@25QOX.^'75`*[Z4S!R/A>[>%NG-H4VC3&%,KI +MPROM=-+HMCY%)N`"KUU<BF,$2G>YE.F-6(7.^(;\'4QA@^Q7*UJ17\0=1=5< +MZFUQ2Z#8N)#WY)]]E3Z=;FXN`]V5U%E1;3HC'U7FRRV]&&.EJW8&L;Z=E:%0 +M!NX5%U9K6Q(V[IA4<YN(*Y6N\BS>WK*=(Y7-7?G]0N-+7'3^RT;MCZSX.%H] +M.LZ5"V#C^8Y6=;:WIF].Z2*;AJ))706%FP``-5>B[75@;<+5MW,ITY<8"WC' +M/+)<M+1@:!I&%:9:4Y@M6%?^(;6U<9J"1[K/_P#.M`5L5!VR5O<CENNHN^D4 +MJK(T`#NLVXZ54MI<P$CV5OH/B"VNP/6"3[KH&TZ5Q0($%/69-XYV.1I14ECQ +MD8(*I]0LG4W:V;>RZ+J?3#2JZV<=E5%)E1A:=QW7++'7%=\<M\QA6M5[:D1A +M:5JX&">56NK1U*H2V?E-;EP,+E.'2S;7ID%L0$MLZH"BH$>7JG=-4>5U[<UJ +MD\'=RFU`"`LRG4@R2K+*X(W51=IU(;&I3MJ@;'99@K09+AE%4N1$"")R5EIH +MBI()F$+GQN539<0!D3\IZERV03G"HLNKL&^ZA<\..3E47U'.,CNIK9WJTJ-K +M=-@+D]:0?9-3<!F$3G`CU&%649<`8]MU#7>W3A'4(+L9&RC>!&<H:4KD@M)A +M9U8')C&T+3JL:X$!5GT@UL&,*:V,VJWDK.OFAQ(;_HM:Y87/V5.M1(.RD@Q* +MED'DR<'.5G7UK;TY[KHZU%P8=(63=60?5.K.54<U>6C"XN#C]`L3K-E+"0S8 +MKN+BP@2!C9974NGZV$'93U-V/,>LNJT7END$#W61<U*A)>:;@!R.3\+TOJ72 +MNF^0T>5_,`AQX/NN3\06MM3)T,<Z<XG"W+)PW[[Z9W0.O5K9[6ZX`&>?[+OO +M#GB)MT/++B';1_L+R/JE-S'DM'I.T!2^'>LU;&Z`.8Q!6KX_N+%LO%?072KK +M14:X;E=]X6OQ5IM#SF(7C'@[KM.\HL!/JB8/_9=]X=O13<TAVZ8WZ\_DQ^5Z +M0&L(G4,I:&?XPJ5I=TS;,/<*3^)IKU?NO+^T_/.Y=+W%I$959T`[J>M(,0(V +MF=U7=(?&5Z;VTC<09`XY2JX`;!VS*?&L`NB3DH.=\;)0F@D3G?=,\.!S@^_* +M:21OE(N)(!=/RH&R7<;)`ZN3D<!.R"9G,[(<;YP@6)D%WLD#@$.^Z4`F9,>P +MA(#$?N@/`<07`\2G<X08V*%O],IW#TB!'=%(D3(Q.Z>1G.Q0_P!'O.<HL:=4 +M(AB)_JSV2,%H2<?Y@`A.0)'$A(I@.Y3F.#.,IB0#B/V2`)J$;#]40Q;G)^XW +M2[B=TAI+^XXRFIP,@(&(EV_Y<)&0)`P$9PS!R3&$!)P3(A%+$23]$[9QF`F# +M)P!A(@8$P@)O?^Z1:"TQ`)Q\IRUHI?F:3.R%X&D\QE`Q&./NFGD1"<`D8!A, +M,G,Q[H'/R.Q3'!DQCE,X;QC,)VM$-<1,^_9`61C`QW2:(!.#P@(B!C[IP1.T +MSB$!.D-$;I-QP2F@:=X]DXC7^9#9$`),:"=($SPF@2<(@&Z@9QR4$A?-'0Z( +M&=1&4?3'`7U&HX2UC@YPC@&5"XR,$P[V3#?'&$!W`FK);OD#="-QC<X1!V`3 +MVB24S@=/^J)L,08YC!"4278,@(B#(CD(2,X/**8`8P8W3D8[X2`W))@F,IRX +MG$J!?TB!SV2$@@B3';E/IDF)CB4;6PW/.RH0))DG+M\IH:1DF`4AJ)B2`?=. +MT$@-YE`@PDMW(_5=E^'/AYW4;YA<UT!P,?9<_P!$Z=6O+EK&MC(SE>^_A%X: +M%K:L?49ZW9_92UC.ZXCJ_`'0:=G0IL;3#0!L%VU.FV@WM"@Z?0IV](#:`J?6 +M^I-8TZ'?<KEEDSC#=;ZB&^EIR0>5SH=4N:Y,[G=!7J5;FK(G=:G2K4,:"3\K +MSYY;>C#!;Z72\ILN&%>KW(IT\QLJP(`+01E*C1-5^J?NN5=I(9M1]5\SOE7: +M;M-,9(,*2VLQL&G.ZLUK2&&!!C*QITE9U2JXU>ZN![BP1C$8*J_P[F5@8WV* +MMTQI;D9(315RQ9Z0X1C<]UC^-.M&RM##@#NMFU>T4R-B!"\]_%-Y<2!\_.ZZ +MXS;SY\./\5>,',8Y[ZPF<"?E<A7\>5_-.ET@']%E>/7/IW08`=)Q^Z[C\"_P +MUZ'XDZ"[JW7*]8L-7RV4Z#@#L#)D>Z[SQX_6-^LW6A^'/CJJ^JP&J02=I^%] +M#?AYUD7UJPN?F!SLOE?QIX9'@_\`$3^`Z=4?4MG$/ID_FTDX!@;KW7\%;ISP +MUAF,?V7++#URX:W+'KMS2;5I;;KG[^D;:L2``"9E=-2@T&&(D+*ZU1:^FXM& +M96?)-QT\=U6-69Y]/4(E4*E`M>8^JNL?Y;P#SA2.HM>=0V.5P[>GI3HU#^7? +MV4E:"W/'*CKTS3<2!`05*X#(..Y5G"6`,->/A.ZH&[''RJU>LT2951]R"V`X +M+>V%]]UIP24A>-`!!SV60^L7$29E.R9P%A6Q_&`DP2)2_BIP=OE9;6NB#REJ +M+9.P_=%;3:NJ>ZFMG'5JGZ+$IW`!''.ZNVESD'ZJ+MO4R-`DH75`2J(NP6[I +MZ58ND?JKM(MM<&NB=T-;).1'LHR^`)2\S8?9:A2:UN3LH:C2YY4KW`@D'/RH +MWNS@_P"BJ*U2B`<M'OE0OHM/?93O?ZB21'LHO,SW4%2K1&F(E5&VC"XD[RM- +MSVZ5`ZF0XN_I(51FW5NT>ENRR.IV9+3S/"Z&HTZHX56XI!P((B$B;</U&Q=4 +MEI;@[K'ZGT2CY)<\Z3W.5WMY:NF0W?*P.N=.JUIW'NKZRL[>:=<Z9T]C=)R9 +MSNN1ZI94Z3M=,F"3$<+U>\\.VOJJ5@7.))DSNN;\3=`M?))INTD;2%<<KCVW +M;*PO`?539W+070,"%[%X=Z@*K&%KP9@@KPBO:NM;LN#@(,2O1OPYZBY[`VH[ +M((&-E<YJ^T3*;CVNQOHM*8UC92_QW_6%SMK=4A;L!)F.ZD_BJ7<_=.7+A\97 +M4$G<?[[*!PEA=!`&)!V5BX=AV?;Z*H\DN&,;A?1KA0/$R1A#48=$R43_`%'X +M0SQL2B!`]<">Z3@!!$DSRG+CI`!PF=)`QL-^ZBFEQ)=RG@`Q)DH0X3(G*<.( +M.)5#P8&?LG:3$1DI,)&"XP0FGW_5`8#-&"9!VXA(^IQP`$.-0DY'9'J!,.)# +M9RE@$_\`+`G=(B!EVV(2`]6#A$0)W!$2B`R&X.4Y+HB?NG<0.,).@"/K\(&U +M&>2>4.2#D=OE/(`:3N<)SD`@B>W"*0@.D)F@EV-Y1`C3&`)V"3G1,``H$0`Z +M3A!$CL$3C!R`3\I`Y&=NZ!A.@-G!X3&200C=+8$C*;4)WCL.Z!MP)CY3QB9V +M_1,2)WPD\C&-T#.DY.\II@DD`GW[IM7J[)SET[(IR9C`$#;W2`)@3!2&!@"4 +MQ+-,YDH$<>G$1E+`<(XV3-P?=.</VG"B"DZ3.9*8SJVVW3ZAH]TA&G!@JAFE +MT&,<)Q.DG)">)!]\X2C$NR?9`P)TD'(E.R3)T_=,V"#@R>.R=A8706F3L`@0 +M)D1,S&R-XGX[(0<2/L43W"((R$`@F0`)3$SD#`12.1$A,<F.Y4"R<$!-D';" +M-D8!X3^D@X,0J$QIU?[A/480-Y,;2K-&"S2?H.R,4QDD3_=39I4$`Y'PIK:B +MY]1L`G40("E;2R`T&3Q*ZOP'T7^*O:9T@@D?1$MU'5?A3X9;7:RO5H[$1C?W +M7MW0K>E8VP,M$#E<CT1]ITFR8`X-$#<_[[*'J7BHUII6[RYNTB<KGGGIRQQN +M5V[+JO7&!NBFX2L1]:I=.EQ.5D6#JE=P<Z3,86YTZD!$S"\^63T8X:7>FT&L +M:'$;=UH,=C?8J&BV:8#0K5K0+M^%RM=I#TF%S_>%HVC(`'9-;T&Z1)QV5FDT +M8(*RUI9H1N["DR[!4(@;'=.7EA$<HNDAH-<2-N94;[4G\J)E729[*:C6!,G? +M=3VTNE-UH\;3)X6!XCZ#4O!G)RNS\^D<0GI&@1F/E;QRC&4V^=OQ$\`=0K.- +M6@PN(R&_=9/@A_C7PH*E.UI.\EQDTWM)`]P/HOI^M9V%=OJ:T\255O/#O2ZS +M8+&2?8+K++-5C6G@W3[3J'5^HNZAU4E]=[L3.,^_"]E_"+IKZ6EY$`QQ\(AX +M5L:;P6TVD#;"Z#HC&]/;I&D!8RR28<[=I3.FD![1\JKU!H=2,1E9(ZL(`+\# +MW05NJZFX.3ME8RSCMCARSNHO<RYP8@JQ;U=5,&=MU2NW.JOU<3/=#;57-,$1 +M.%YYQ=O19PN]0JT_)P<K!NKD1E6.J5#!))'PLBJ`YQ]1,+6]UF22%6N'.P#A +M`P%SMC!PG93D@QGA3T*328.YY6ML]AMK<N?);GY6I3MP&R6P0$=C0B.<*Z:? +MIR``H2,NI3TDX]U'7I.(P%JFB!E"^BW1($*1JL"Y!IGU3E#;7<'\V%/UL!K? +MCE<_6N7,J:0=UK3#HZ-T7P9PKUK7]_=<Q85G",K8LJI=$HK<\_\`E",Y0&M( +M_,J>LP/TA#YT'3Q\K;*\:H([?L@J5=(D@J$.!V=[[IJSI&#*!5JL`F!["<*( +MOD\9"'U&9W0M!C.,;**D80.<3LG>[U1Q*B<^-MR4SB=."`FTT*070<*-S!). +MQ0PZ<G?A-#B"<_Y*RI8&HQIQ`,\E5;BU8]L1^4*VZ.^5%(D`X6MLZ<[UCII< +MQVEL\K@O&'1:F@N8#MG/RO6ZU,/;!&%C=8LJ3@X.#=E>*SO3YSZK3K6US%0' +MT&22/=;G@WJ#J5W3;,-D3&W"['QMT2TJT7O$!PG^ZXFPMA1OAI$M!WGW6[JQ +MJ7;UBROV.M*;IF1O*E_C6+G+"NT6=($G#0%+_$-[E8W7-\XU]#JN#`YY*J52 +M`?1'NK5?#N!.ZK5A$C$;1"^C]<43R9/?LE$24[],3J@SV0N_)^B@8G.(2;#B +M9@XPDT$X`^R$MAV1D(%$)",SLGW$%+2=])`]T"D:0($^R<QP"D6ZG?ETE*#' +M&-U=!XC)/*<@:>Q]TH@"?V3M&=X^$0TDQ@8"=S1&=B)3R`-`!GNF('Y3OO** +M;WTQ\)&#G!^4OZ)PD-\8'NB:,!)C8)$!I(TIV``;_?*8S.P^RBIKAU%PIMHT +MG4H:`X%^K49WVPH7;[9/9.\&-XG@'=,9+AD&.Y5^AMC),I;X**1)*%D:23,H +M'='/Q,IH&DR-]DPY=)GY3R=$G"!F@-)G;^Z0@D\A.&NXS*?4?+#8&.VZ`,!Q +MB/A(D!I:0`/;=)P,9,2-I3<>R*(1$;'O"8M$1!'RA^3"(S&Y"@&)^B7>(!*( +MQI&3JY28`7?YJH3)B&F`[!2#6"?4F]IPG<UP&D_*!"`"!E$6F-HGW3-;!W'N +MGTSL,'E`@)S#1PD&@$3_`-TQ&0!E$X''Y8WE(':`W/V/=/I))@),$@Y$^YE) +MK2!,!`SFAS9!SM\IPSN)2_,2(A$<.&,`1E1"#<D@1!3-&IOYAOPIJ;):2""1 +M_2HWB'X@HK0LZ8-,8))4[J(+<&",Y3=*!-,8!!5]E.7CL."L4Z1]-L/XBO38 +M#^8P3E>B^'*-'I%@*E0LUZ>#"Y3I56E9GS-/JX&Z;JO4;FYJ>6"X#L"8"7+7 +M3%Q]JWNI]<NKR[\JE4=H!C3.X71^&K-Y8'/G,87/>#^DNJ%M2H)F,%>@=&M6 +ML#1'/'*\^==<9\B_TRVT@'*W+2B2T0(5>RHDN&_T6U:41H!7&NV,%;4,-&RM +MTJ3ALBH49:%9;3TK-=)!4F0-M]Q*GMV0#(F-E'1'J^BMT6SB$;]0BF=\'V*) +MU*?@(W,=P)"E#'Z?=#U5C1&D"#(,PCIVIU=L*=K3,'=3T6:LB%E?52?;.!]. +M%&:-0#?Z+6%$N(X1FVD@IK:,;RZ\2'$0$%6K<M:`#*W76S2(&?91FS!!!:KI +M&)Y]PT9+DS;JL<$;+2KVS0(A5:U.FSME32\*O\35=@G"=MP\'*&KH#C#=^R@ +MJ%[L?LII=M!EZQH.5'6Z@S3+?NLXL,[GZI-I^KY33-J6K7?6W,IF-$>RD`:U +MD",**H^?3W34B;V=PEWIW"NV%`ZQC*AZ?2+W_P":W[&T@`D96:W.#VM$0`!M +MN5:-`%L3(CNK=&UTL!")[`QIDJQ&<^F&S`V]U4NZH:R-NZL]2JM#?W6!U&X] +M4S]%-M:VI=;K:FN`&^ZYBZ=-:/HMOJ+]605AW&*DD+6*7A=Z>X-<"?JMBV?` +M&GNN>LZGKAI"V[)P<-BMZ8K2IO)]1V'"($&(Y5=@=C.ZFI%F))'$*[1,T&1B +M$;((AT(?,:!L-E&*X)SLLVM2;2^ANWU"@J/DF-/R4-2K(,<>Z@:USB3G"SMJ +M8K6(GORFIQJ@C?*9@EN94K&9!Y5BZ$6C$#(0&!,B%9IT^"AJ4A&)`5TS5&L1 +M.^_*A=`,GA37+!JGMW4%3+(!6F=&UC29$*EU1NJD((D^RM0`-Y3,8'-AQ)2, +MY.!\3].N:E-^EARO/+VWN+/J$U&:0X[+WGJ-JQ[(`PO._'/2AJ+PW:2"%TQD +M8]K.&+:5&FV9SCNI-;>Q_P#WE5MZ3FT6MTNP$?EN_P`+E=)IX77R_`C.ZKO` +M$G^ZL5LDD'_55ZL`[8/=>ZUP0C,YPF>#`C9$`-)W33$S*&C#`$2F&X<,)3+I +M!33G=0.7!SB?V3`8W,>Z33F"/[I\3DC*H+29#C!]A,I&.3E-`G3LG/I&2/F4 +MV'#0,A,<SN>Z0<(,PG)#0-L[A`A(,GG9(G&YRG).F!L$C!W,1W1##`P?HF!@ +MD(@(GLFQO)12'Y)'ZIB9;JGZ2G&TSD8^4S]Y;(4")X(@H7&#/ZS*-P)$Z8)4 +M>G)(/UX5-$UQ&0?E(?/*0!!,)X@3!0/Q";U;$[)V_E2'YIF90."9"3S@<I]G +M1N?=`9+23)0*#I,#/[(2""#_`&1;`B29Y*4%W'L@'>$P[&81Z8(S*0;V,^Z* +M`?XA&$33Z?=+CG[;)-V]E`^H:?RC='3+7.EY(&TJ,`!TI^<!#0W#GCW1>=-J +M*,-`F=49*$X$<)G-!@,G43D*H0,8@?5.3D0!A#ICM@_=.TD?1021,>G?&4Q` +M:>X3R8`:9`R,X0PX.#?U[($R7&(E$6[%KI)W'9#!$Y1,^,'L@-KO1V*`3YFH +M\H@)`TPDS$3QN$&MT4C?A;-)M-U,Z78Y'=9/0:>JH&MS\K6KL%%FB#/*Q>S_ +M`!7J57`G\P'>5I^&[9UW>`@.C&^ZS&`UZN@-R>Z[OP/TLTRUY'N"N>66HW(Z +MCH%B*=!GH"Z;IU!K6B&K/Z;1R#$+>Z;1B#W7GW]=,8T.FT1`)"U*%/(@0.RJ +MV+-+1[K3MV"97.NTB:VIG3MA6&4=42E2;#8VE6Z%/GA&I$=&@)_+A6*=&?\` +M)6:3,[05-3I@[?:$:5V40.(4C*$M]O96J5)IYW1BF&Q&Z:6549:B1.%+3HMD +MX.%:;1Q*D9;SM,J6&T#*>WLC\LAL!6Z=N1`1&B-6VRK%40P@$\J-P(_=:3J` +M!.,*)]($0%$VR;BGJ!G=4*]OK.0<+=KT@W,`JI7:UL]NRB,2K;1@&/A15:+` +M!`,K0N2)G[`*G5(CU*;%5U(;DPH*M5K<3A'?W#6-C^ZS!4=7>0V3QA#6UD5" +M]_IX5NTMGU*@)'T3=+L7ZI=RM_I]F`084M;F)=(L,R1]5OV%`#C906-NYKI# +ML'A:5`0`8^4C5B3RVAA[PJ'4,-*OU9T[0LCJU0L80,CNE28L/JM1NDDOCV7/ +M7E4%QRM'K-7)B9*YZL^:D:E(TDNCJ9`S*R+X#(,"%L4V:QE9?5Z6G8+>+GE5 +M6Q)\[?"W^G@B).%A]-9#YX[+:Z</-K!K<*7)J8\-$/.`!,)5''5V]EI6]BUM +M`.]LJ%]JUS\K7.F9K:L:@T1V4+GSN0!W5FK;ALZ9^JJNIN`/IF5S;#4J`"!$ +M=Y4M"LT$`'?NH7V]1QP"HJE&JW+6II6JVHTB-0^BL4-,@@Y7-BI7823("GI= +M4=3YE7E+'347-&T)5C.Y6-9=3IO(!=G=777`&1F?=:QK-B*[;),95-_H!P%9 +MK52XA15QC!E;W$5"[>3[HF;D@_W4-W@]Q\IJ)<>?T4+$U;+28_58W7K(UZ#B +M6SV6N#)@;?LH[MWE#N"NF-TX91Y[4L'-J%N@X*;^!?\`X"NKK,INJEQ:)*'R +MJ7^$+ON./+Y#N3+M,$_)4%PYQ`&HD#8RK-<:B`V/5Q,0JE<-V:\P,;1*]*(Q +MS!]T,^DA%B#F$V6ND.RTJ(`D`$PEQ[]T[AOD?"3V@#!,';"!-/JD&(]T0,NP +MXXV*9\BL[4S3F=/9-`/,R>$$C=()F2?F$PR<X3.;#LS([[A(DY$X[JA-C3D2 +MB&G&)([\H1R"92:`>3[!`3B-6!$Y2:-3PWOW2B=,'/(3$Y@!02,)#2,04&-6 +MV$G1\^R:0!M,@*A'2TDDQ]$P(P=,Q]D0PWN@&#)P(WA%27%4UG%[PV2(,"`H +MQI@[>Z08#OEQY2`(<"Z80+TC&)3#:0!"=H.QC*<M],_E0,-H@2G9I+@1GV2# +M8),[)-@51)QL2@=S<P8Y2]ASV3/,&`9PFG&\F)D(AL\F4FC)WRG<"?;^Z0&8 +M!Q[J*0@F8P>2F<`<@X]RG(.G\WT";8Y$`_JJ$V)SB/=,W_ISRGTD-G'/*0C2 +M21!X'=`Y$_/LDQOJ`G/ORF!!`Q]47],0-D!%HV).>R$M@0#ORI/3_0'("/27 +M&2=D#.$1P.Z>F/5D[);#;ZA"S88WYA`8$F92@2#KR>Z>89@2A`R<">R((MD` +MZA]$3.T'ZE-&T[=@G+73IB>%`;/2\0`83MU5*FV_8(*9),;*WT^BUQD3\(-C +MP\?*8"X>P@*]>.#OZM@=E2IQ3<UL&#M[*Y:4C5J-;!(&\97+*\K/RN>%+(U; +MQKVM)@\C*]1Z%;>70:V`)7(^#[-K7M<6@>\?*[_IE.=.!G]%Y\[MTD:-E1V& +MRV[&F!`P)6?8T@&:C)_NM6RI%Q`C/=<[7;&-&U9Z1Z<+3M:8E5[2EB./=7[6 +ME#?=9=(L4:8A6Z+(XPHJ#/3D25=MV>K))114VQCG?"G93<8Y*EMZ4%6Z5(1@ +M1"U$VAHTR"9`^ZG;1U#:)1LI@'T[JU09W(CE-%J"C;Q(`R%89;D"8W4LM#AG +M=$XC3(X2QG=1>6!QL@J,Y4T^O'U0N!T$`[J"/2(@M4-9K8]U8,=Y"AK"9VGA +M04KPAHP2LN]+0"=EIW8AIET3W6)U.X:`YH(6+6I%.ZJ9QRLZ\KX(`SV1UJI< +MXL;RHA:U'ND@=UF+I2<U]R\``K7Z1TF(&G=3V%BSS`0`#.P72]&L2Q@Y(.ZO +M:ZTIV?3M+1+-EH4;4-`&GZK6I6T>F`$YMI;/*UI95*@UC3^ZL$`-D;%)M&'3 +MI@)G@AN\J-\`KO.GNL;JKO3(XY6K6.!WX67U$@L,]E$TX_KKX><PL&?,K&"M +MOQ/N[]I6!:`FN-HE).&,FO;L)I2?HLSK8:&;[+<M@#1(*Q^N-),0(A:CGW6= +MTN/-#"=UO]/HAE36TB%SEJ_RZX.-\9716Y-6E((QF0L6.DK?I7-)M/\`-^J= +M]U;L'])*YRNZL/3/J'NM#I%C7J-!J$GZJ7*QOTFMIZ]\UQ<0V(Y47\4V-7EG +MXA:]GT=I:"6@K1H](H`QH`^G^BZ3#*N.7DQCE*ES5+891)G?"@UW;G8HNCL0 +MNV-A:4A+F-'T4+J5H)/H('"Z_MW\N?[T_#BKA[J=,^=2(/PL2[O*9K:0`%W_ +M`%*QI7-,@`01D+E.K>'',<:E*,"<J7"SIO#R2]LO348T5&.Q\JWTGJTU?+J. +M_58G4*]>WFDX.^(5>T=J.O7Z@N=GX=-_EWS:K7LF9!Y4;JD3)E8/1NH#%)YY +MV6M4<'&6D0=H3_#1KIH(G49]D#):V=7NB![C/LG#=+=$9*U"](VN!=`&?<IZ +MS`6.U9[05$?^87<A/5J_RR=EO'MQRBF^BPN,0F\AG8)JCZ9>200?E-KI^_W7 +M5P?'U8`%QU2,S_95JA&GXXY&5/<..HD<?15ZCGEQ$-''U7L<T;P-@`T("(., +M%$\C)D8.0FQZ2@1EL@[C$H,<E$8F0A=!$D\=T#@M=JG4#P1_=)HDSC=,-.DD +MB'#MLG!`!`_50%'J@A%#2_.!'W0L(B)`.\RD"6G`G*H0:/I/V3AO)'V2:Z-C +M[83`M$X[YE$.UHTQG.V41$#O[E,-(R.4[C/]6/9%-@N_=+2T$['^Z:1J.G9* +M>W"`B`6D3/\`=-I$3N-MR4X@M$P=/!35B`XM!+AR=N$-A(AN$VF1@?=%4+=) +M$1]4FX!P2@30=MCV2<W>?E(F#&\8RFG!SG9%(F!`^"D!Q/T2!`/,I2-<@$0B +M'<-1!!@3"%['DP!MB`B);]1RB)D2XR9Y0`<-DREI$0=D\MUD@[;2B9),B".0 +MH!P03,<IBT:3!F43C,Y^R$F`?5^7"JA:-P1O[[(],4QZ@9[(0?41!*1DG),2 +M40\`'&!RD=42#[B4[)+,$9,I-,GU'`V^44Y._J1:AL"A,C(/.Z6I-(8B792- +M-]/)!`(D2,(\AN")&4,N,R0.X"!VZM\PGI8<)_[I3`&W<RFV``.1.2@<F9`R +M.Z,NG<GZ(6-)J`3MRE`:)!$<*"2W8Y[A^JVNG6;VMD_U+/Z6QSZLC!G,+K7V +MWEVS06Y/`4J6LVWH5:K@P3''8+4Z?;%K@UNHYS!Q^R'IM-H9#X).<\+7Z!0# +MZ_J$CD0N.5KIBZ?P?1:UNIQ@]IGNNSZ=1)<#`6+T.V93I"0T<X73=/IYWCX7 +MF[NVXT;*D-#<$!:_3Z.F"(@*GT^CZ=EKVC`,K-=8O6E/V5VA2`SRHK-HR`K] +M!HD#*-Q)0IC8A7:%.(TA0V[,XV5ZWF`8E%2V[,#"M4VDC`P@I`00,0IZ$C*T +MR36$>EW_`'4],#5'9+^K?/.$3()$;'E0-4;.3VW2`,`$R1V1.`'NG8W2Z=_? +MNH!T`YXV2%/<SE2N`D#NI&,!&?N@JFD0"0)5>[+:8DK0KD-,3L.5S_7;P,81 +M.2LVZ63;/ZU>L@C4N>J^96JG<B5<<RI<UI()^JUNF=-$:G-$^ZY[;Z9%GTUQ +M!<]ICC"MNMVTF_E@]H6\;=K&Q_9974=+'&9V5TDNT?3F#7LNHZ32:&C&`N;Z +M29JY75=.+6@"-L*XM5H4:(<,`&$-2EI)@84]"JI:;0\C&ZZ\5GIFNI2/<*K= +M-TCU2NA;:MVC!5.\M`9V'NI<5F3F[QL#&RQNI$$.]ALNAOZ8;J@RN?ZH``3V +MS\KG>'1QGB9S1JS]UB]-@W!+5K>+B"TG;V6-T36^Z[:3]E/C&3IZ+8MS!SLL +M?K+<Z=^5NTJ?\@>_=95_3)?EOR4E<Y&#<T?+$B)&0M+HEZ�\S*:O;:J<PJ +M#0659_1:LVL_#H@UCJQ>#/;*Z+H=:EITN@G;"XVRN@)#S@>ZU;*Z-.'-/U6= +M:JW>M.\M7-;3D\*AU_KUITZF2^HT1W(6-=>(&6]@XN<!]5XO^)GB^O6JU&-J +MNP-@3C]5Z<.MO'GWIV_BS\2Z%,O;3K8'O_JN0J?BJ[SQ%<P8V/\`JO#?$/7K +MVXNG`5*AD_E!.5GW1ZE9U6/NJ%:FTY&MI`(7;]JWA)I]3>&OQ#IW,!]5IG$$ +M[+N>F7]#J%MJ:09XE?'OA?KE=I:"^#N).R]P_"#Q,ZJ!1K.]0.<_*XV7"\EU +M\=OXIZ2RJ'56B"1A>=]6\WI]SZB=(.0O6[A[:M"<&>%P_C?I+:]%[@T`1O\` +M93/'<X=?'Y/E8]K=,JL948\2.Q72])O?.HQJ]2\ZZ9-G?FWJ$@'8<+H^CW6B +M]:T.])[_``N%M^O3K5U'74G;F!"EID'(.>P4-L-5,3!'96*3(GNMPM0W!#7P +M<SNH:M5NF0,*>X:&DR>%0N7RSM"Z1QR+1J]0>(*7E'_&%6\QO^RG\QO;]5UT +MX;?(=S`,`AP[]U7J"'=YR)4]P6DQ(D<GE5ZI;`(,[X[+UUA'/&X&X49``!&Q +M1G3)GE"8@;'X40TDP#E,,.G8A&7$L#3$`R$((&44H$D&)PD\`G?(38U2)SLC +M/Y8QG]40P(R!]^Z<:0Z7'&^R83SMPD021P@.D01$[\I0)V&W?=,W;$@_*;82 +M52G#6C(^436MW<^,;^Z$9.R7^X0)V7D[Y3N;!.KC:$@V$S]I/^PD#Z6D1D$( +M2UHF<E(CF9GA(-)('/RH&`U'YQW1`$?/=`"0>Y[(].F6ELGB#_DJ:"0!L#'M +MRD(_*1F-TGD%VXPD"-,R"XJ*0'H@[CE*'3,_ZI/`(Y^J=FDND?9`@&:#).K@ +M<)23C4E5!D'(D2A8`AH36G8'/L81`[`B.Q/"%H(_F3@8[IH9)R8^TH$3`B"G +MR6:9'>4_Y6G;`Y*%@D9)]D0S6#`GZH]()R=DP!`&84M33H])@#@JJC$`=@,` +M),P[5!(V*1,Y,`%,W<F=^$#P[D(@TZ2-O[I1$"?HF.#Z3"`FMDY(G"9S"XR" +M??"<#`DP1[ILCU<?V1"`]A[>Z<`.=$B?V2`#L1_V3DD`8CA3H,`<F28V[!.W +M43E*"=L2IK5H-5K-LS*#J/`71ZMY5%31+>_?V6_XP8VW:VFT-U;=H5[\.6&C +MTXAK,D3\+/\`&.IUZ6NF)V"XYYS?JUAX[;[52Z)0\RL=8+I@8*[+HEGH:V`- +MYPLCPO:%T$@D[X7:],M0W3I&%P\EVZ3AI]%MA`U<KI;"B&M@9[+,Z50AHU#E +M;UE3U$2V,+FU(O6#7:1@`K6LJ4C\H5&SIF=_JM>UI'3[^RC<6;9@:9$*];4S +MA0T&`$*_;T8Y*-;36],`CLK5!D-'LHZ;6@*>UAPGCL5=":F`0`3/]E8IC$<0 +MHF`[*:EL!,!6"4-]0,HP!'RHV[_W4U(2)[J$`W>8(A3,9)S`A%2IAQRIPT!N +M4T(6TQ,$\)5H8P03E2NTB?=4>HW+64YD*45>IW(IL))7+WCC<5=,D\JQU>\= +M4):UQ*/I5`$!SQ)]UQRNZZ2:2],LVL`)9GW6DXTZ+,B!W0.<VF))B,K!Z]U- +MP!:TF"/LIO2^NQ^)?$-O947_`,QH`]UPM;QK1N+WR65&DSM/^JI>+A<7K7_S +M#GW*\TNJ%?I/7J=1Y(:X[Y@J7VK>&..^7T;X:K"XI"I,SW74VE2(_P!RO//P +MVOA6L6YS_P!UW-O5D`XE7&\)9RV*50"`#A7;6L0T$D2L:C4(]2M4:OW"Z3)F +MQLMN1IW56]N?285&M<:6D3^JI75X,@._T6KFDQ!U&JV""`9"Y[JC_28C*T;J +MX$.AP^%E=1?JIGV7.UN<.,\6.!!D[K&Z!J%R6G'Z+>\3T=3'/VC]5B=#9%WM +M,G"EZ+'7VXF@`<E5+F@#QMA:EC2/E@XRD:0-0J1AB/H$B%E7=!P>2W8KJJ]$ +M1$+.O+8%LP`MQ&`ZB1D'/[([>X=3<`XF#[J]5MP&$9SLJ%S1+7'>.86M;5<N +MZ(O+:`001C=>4?BAX9NF:JUNS#1D0<[>R]/Z9=.;4#7-AOLMFKTVTZE;::C& +MND=EK#+5<<\?KY)\,7%ET_QI:W'5Z`?;TJFI[*@X'RO6/_$'XT\$7_X?OL>G +MT[*YO:VGR'TF-FB`X$Y&TA:?XE?A9:W=%]6VH-94`P6#_1>&>(?!W5.FU1Y[ +M/29&QD1$S]UZ\?[>^WGRQF4U^&9T6L0]I<W\OZKTW\)^HO=UIM,-($P8^JX3 +MIUAY3,,)=M'NO5/P=\-5*50755K@7&<K/FU88O9[2HYUJV=U0ZN/,HN:3L%< +M8X4J$3LLN]N&ZCI=@<+E>(N$W>'`>+Z1H5!5:(`.3"BZ7?,?7I"#+MCP5T7B +M.C2K6K]0W"Y#H]L*74H!($X,KAY/R]F&OKU+I%8.MV@X,+0:26R<K'Z!'ELW +MD>ZW'M`9(/RKBEJG>G+O5CGW61>U0`8=\+2OGQ.?E<]UNNUC'&?U7?&..5X5 +M*MZX5"&D0A_CG_X@N?KW;_-=IV0?Q=3_`&%W<O6O`[D#S"7&>%5JN].D1!5N +MX+7OEK(G8`[JM<L+':7"(X7>N2%S2,@$2)R@&>%(X3$ND(1`/?V32ASI(@I@ +M.-T<NR!]<I.+2[`COE`!,[82>T"(TDD?;V1L$B"\#G)_1!IYS]U`B#JV^R0D +M081-`#ADHB!L'?W5@8DNW'Z0$VDGZ(X])WA)S=D#`^F,S^Z8"<1E.W:"=L)$ +M$"90(3$29W14C#FRT'V.Q33@YB.1RF(@9A`3RW=I4=:=3B'&"BS`@@2F<YP& +MG60#N$$;OM*<3L2?H4G:NZ0S$_LBF#=YF$\3.EWNDWDDGX3Q!,$*:#$G;4G: +M3.)38)C=(G$*AR3P283M)/=,"WE.2)B`1WV4#ZCR3&TIL[`PGYV$!,_?@]I0 +M(EP&28"%KB8!/W18#>-LYW09)[J@I))@Y"D-1SZ(IP(;[*-C9,$@>Z)H])R$ +M#$&3V[A(`B#"D;ALD84CRP6X:6#6#.J=QV326H7$XS/PF(=));]`C:9(,#/= +M'#8@E#8!J()&0/9"3#I<V>Z.!IF"`>$PQ^5L'N@.D3.!N-TU0D-@3*3=X@9V +ME$]D@X'R%`!(#F@".,KHO`/0J_5NIL;HEDY*PK.AYM9M,'\R]J_">SM[#IS" +MYK=3LRN7FS]8Z>/';J.B]!I6/3?+#`-(R>ZX+QC18[K@I,=MV*]*ZSU.C0Z: +M\AW&%Y:*K[[K3JO+BO)CSD[R:EM;_ANWAK1I=\KM.C420"6K!Z#1`<UIQ`C; +M===TFC#`,I]<JO\`3Z1:X`C=;-K3../=5+*EM#25K6K02TD05*W%NPIY$A:= +MMC(W5*WVQPM&U:3[?*C2Y;#8PKU!P)WA5[=@(^%88T#8*JLTCZ@)QRK-NX0? +M3"@I`R.59IB1/*"1F'3F%,P^J)^JA;JGCY4]$9R,%3:I&@D[%3T],?""@UQC +M;Z*5[6CA!(VII:9":I7QARJU*P!W52O<-;JSO[J6FEB]N]$S@+G.L]1)!:#O +MV1=9OP`6@Y*Q&%U:M!,K%R=,<4ULQ]:KJ,Z>RW["GHI1!/NJ_1[<""0"%M4Z +M;`T8CX7.1M0N*3GB<_"PNOT&LIE[H$!=:]K0"3PN3\8%S@\,)5LU-D_#A^J> +MNJ?9<=XXZ36NJ(-,B09&%W#Z+G5O4/JAO.GBK3RS"LO&EN.KM%^$[:M&T8RH +M22`O3K0N\L?YKA_"EJ;>H.R[6U>&@">-RL8S2Y]M"DX3$J1U9K6Y.0L\W`8" +M2<!9/6^N4K5A+G#'NM[9TV+R^`)`<LVO>R<N"\W\2_B):VE8M=6`(]UF67XA +MT;FM#:HRL7+ZZ8X5ZHZXU[F5%7<U\@1\K`\/=8IWK`=>>RZ&VIE\'/\`FI,C +M+'3'ZW2!ID1PN>Z93#;T;[KM>K6Q-N[&ZYFE;Q?2-YRM6\,1NV3]-,@[*>FT +MG)RGZ=;%U,$;J\R@`?WE,>6:SZM,021"KOH!_P#3]5JW%`$8(*A%&&G"VS6% +M<VL&#PJ=U;`4W-Q+AN5T%Q0;JG]U4JT&G<#/*VPY*ZHFD9`(*N=$Z@^F0UQV +MV"N]4M@>!LL>O0<QVMLA6KW.74FM3KVY!`]EQWC'PQ;7K7.\D$GL-EK=*NM1 +MTDG_`#6D]OF-@D&<JXYZXKEEAJO'*/@ZA9]2#ZM,%L\KO.A.M+2@&L`"TNL] +M-;5S`^BQ;JS-*F&M`$<K6^>$]99RT;[J%)S(:1]UF0ZM4]!D$K+N65&F"=D5 +ME>BW?+B2`N>6=^MX82+?B"U>RS+78D+DK*FZGU(:OZ3L%U=[U)MVP,F)[K.? +M9M%<505G/5G#4NNW0]`+6M!)(A;AJ,-'4:D'@+G>GO#6#U+294+F$$C(X*WB +M9(>HU@1#>5QWC"[\J@:<P7X"Z7JA&@DN/U7"^)W.N.JT;=N9*]&$^O/E?BST +MOICZEA2J%IEPG]58_P"$N_P%=?T3I8'2J`.^E6O^&-3ES]WQS5W]APJIW$`R +M5:O=+JA<&``F855X,D@8]BO6RC>3J,[\@I2P$Z09XGLDX3).23W0/W'<;H$( +MP3E,8G?!1`9Q"'?!_P"R!O8@GW2';!1%C@W+26S`(3.:0^1('$JAA^6(B$6\ +MG?;"%HR`"B(@Y"@+4<'@)#\LF4#<MW1-((&-^Y5#YVXY3/'<$)H)"9X).24! +M.<!L9^B0.?9!F$T3$H)`6')&3NA?#N8'NF)SN,)MW3!'>$4HVQCW"<'./W3` +M83!L'`4!.;!("8>[3LEI`,28`S*<`:?9`P@`04@)G"1$B-B$6F&_"H;TPGF! +MQ]TS0=<3&.4S=Y/'NH@CEHS@)`#5ONG`(W`^)3&)[>R*?T@'T@CY03Q)E&V( +M(WG;A,V`_@9V"(:28R8E'ID0-TY)#2UKX!W2!@QW0)H.DR["+4(@Y*#$P#NG +M`;OPJ&D`@?NB<2`1&>$((!QD)<G5'V0&R'-C?Z)G-C))]A":D&EI#0G@C&([ +MR@>F)=)!PC,MQ*"F,F!"EIM+GC2TDSG*@N]%8'7;7`1G.%ZAX4N7&M3H:H!@ +M&%S'@SI%-U'4X&>Z[?PCT84KP5BTX&Y7F\MEX=\,O6+_`(W:VAT@PXDQB%R7 +MA.@'W7FR22>5L_B9=Z6-H!RK^!+?8N$Y[+CCQ+8U;P[+H=``-DB>5U73*>1C +M'98O1Z0$8PNCZ53AX)V4VQ(T[)D1Q[+1H`$P!E5[1H!SSP5>H-;M*S6XMVS9 +M`,%:5N,#"J6K1I_-^JT+1L-U;A%6J$Z5:8`(]U7H@=HE6!M`$JJGIQ,*=CL1 +M.%!1VR-E8HB8,9*C6DM$?4*S1:V1.%#0:6^TJ1U4-W5V:25:[J;]-.GC<F=E +M%=5XY_55[BY`$ZMUGW-QO!E9M)%FYNL8&8PLZYN"9R@=4)D:OHHG-+C]%BMR +M,[J=1SGXF$NFD`^KNK56VUSB%&VV<P86+MVFKPV>G5FM``6BVKK:`#"P[*F\ +M/`+EJVI(@?ND6Q/4<\LCA974+!UP3JV6TQNJ!PIQ;-TSI]UO6V.G%U.BM827 +M#G=05K#2=L=UV%[0:&N`;E9-S1;L`5-2+.6/96K6OD"(6FU[64LIVTAO^JAN +MA#2&\+#2IU6ZTT708,+@?%+[BZ<YH<0%V=_2?5:1)@K'N[`YU-3MJ33PSQST +M2]JW#G4VN<)69;=+OK=C7.:6EO*]TN>F6[YU,&5D]1Z-0J/T:0>(6KG9#'*N +M:_#?JU>C=,HUB8G&/]%[CX=N&W%HTC)/N5Y=;^'Q1K-J,:`9X7HW@FF:=%K2 +MXDQNN/,K6=F4;74&`T"#&0N9-$-ZA`&Y767PBD8,K`#`;[5L96ZY1M]-MR+< +M1V4WDN`("L=,9_(:8X4U1OK.%TG3G6<ZE`@A0U:9#96C5I3PHJM*`<$K49K* +MK-!/^2J7%/>/LM>K1&8'TE4[FF0#`!51AWM)L:EDWM$`D@[KH[JB(]0"RKRB +M-41^BC6G.D/IU"YI+2M3I=X'0UYSLH[VD`2"/LJ<>55#FR"J6;=`ZFVI3G"S +M.J6@+.ZGZ=<RT!SOD*2X<UV(P597"RQR?4K8"8"P[VB0X@$Y79]1H,<3PL*] +MMOYI`B%N\PG#&HL<*@)V[E:#'M%/)!)&Y45S2%/U1D*M4K@-U2,=UPUJNO<; +M%BX&)S/NM`NTLV6'T5_FD$#$[K8K5&LI29F%UPY8RX9G7*Y92<22,+B>AU#> +M^,=.N6M.P71>+K@MMGD/CTG=9OX2VC+KK!K%N=>Y7HG3SW\O7>EVX'3Z0#?Z +M>58\@?X5IV=LP6K`!B%)_#M[+K'E?`-Q)JDSG=5WP<RW'ZJS>.EY@0"<<JK5 +M?G!)^5VKLB<)&,DH,[`C*E<1.VWO*!Q;I(@ZIP>(4-!R3,),'I(D=Y3EPC`G +M*$F3/]D#N)VC?A.2YP&HR>QW0!_^RG)Q&^-^Z:#9!B-NX1GU.)(P3F,)@8G; +M/UA-)D-)$#8*AY$!K6DG^R4XVV288[#Y3N)!(TX]U`S2=XA-F8C'=&S:8QLA +M<[.V1A`T@-T@9F9X2).F83NRT2`8"%Q((B$T'`)]1!SRF<T@Z<&1/=2LK.;E +MI=MI^G9`]V9C`[*J$@Q^6?A-)&8*)N4S@-YE`HR"3]-D],P8C8II'=(QI'Z$ +M*!R2-FE,3&THI`&\D'9`"),H$>#.R<9]Y2!W`&4[2([_``J"#HD&"(V*8$;C +MZX3$B,3GW3LB,$SQA1"8`23JX3ZMH/RG%0:1Z8@S,)C^>50\C5P)2)$$P/9, +M=$A$S000XG:0BADX[)-/9.V"1.>"B,:1IC"`&"&_*?&Y@?"=X$0(CDII!,DX +M&\)H)OOE$.^`WMLD0-YS&1[)@?5B/[J(=ADB`M#H],5+EK($SLLX1W``XE:O +MAMS/^(4]1`$J9<19-UZ1X.L7-HTSGX'*[BT'D6VJ,`25B^#:;/X.F&Z5T=YI +M9T^I$8;_`&7S[;M[,L9T\W\;W)N.M>6TB-41]5T?A"EY=LR2)A<E??S?$3R9 +MPZ%W/0*(9;TY'J,!:O&+'DXNG5]%&V%T?3&-P,@\K#Z'2'E`RNCL6P!@CX48 +MC1M)#8._RK]!N0"JELW`D-^5>MFR!$K-:BW:#(,+0MP!OM/=4K89VV5RD1GD +ME%7*)C`&RFI27*O;\*S1&>))V2M1:I``S*LT0,$E04FY$J9KH&!NHJ8OTM]X +M5*]N!,:LA/=U@![K)O*^IQB=E+5B2M<:G$`D*(ND$3E5M0D[H@2,0IMK20X^ +MB-CA`(.5&R'$#E6[>A)]E%!2]3NZLTK<$"1NI:%L"9A7;>B(`(5TOLJTK6(+ +M6Y5RWMR`)^RMV]NT1'"L,I,V5F)[(*5,1B,=U.UOHB%,RB`,DPK%.@(!W6IB +MSMD75OJ!.!&2LJ]MW-<3NNJJ46EN6CX5.YMFO#F@#/)4RP=,<G*Z71@;*-]) +MSC,86[5Z<W48F"D;"&@=NZY>KI[1S_\`!S,A4>IV8T'V755+8`0,E9G5*/H( +MVQ*FE<)U!OE.?MA95-CJESM,E=9>=,\^L0)AVZL]/\.`.U8.%B[IN1B6=H*F +MEI$+J>B6XI4P1`14NF"B[;;E:%*D`P8XX*2<I:J]3>!1,[A8]@T5;V?=:/5W +MM#2TF.%#X>M]5?61REYJ=1TMC1B@&B9C=$]FY.ZFM9%,<!'5`[_5=XXJ%1I4 +M>B2<A6:S=1C:%`6_>%4JI6G@?*HUQ.P^5I5VAQA4Z[(;I)"J1GW=.1,02LVY +MHF3^F%MU&C3@@_*IW3&AIG[J::CF^H4C!D[%8US#:G(@[A=-?T0YC@!(6+>V +MA#C@&5-MQ3MW.#Y!P<K0;5)9E9_ENIO@"0,Y4[7X@'C95SRA7A]&#*R[]OIG +MGV5ZX(#9CA4*YD<@+<<K&7?,+V1)G^RY[J-9].OY;1.5TMZV-7[KF^K4GNN` +M1,$\8A9RGTQO+H_#%*+=I(@]U9ZM4`)@^RJ]!?Y=D&@Y`0]2\VK3JN8,,;)R +MKXYPF=<GXVO/Y6AID@[RND_!GIU6F&W#@<G405POB=YKW[:8[QDG)7J7X14Z +MK;*DUV,`8^B[R<R.&?$>CV];31:)B`C\_P!U7&!&HI9_Q%>OT>/V?!5TT3J( +M#>T&56J@1+3DXRK-P/YG`/;=05&>K2X<*O2K$Z9`!!^4GMTZ02<Y([(W-&WN +MA,2>W!)4`;B,;IB,Y*>!ID83Z,$E`+A.!*9A)&Y`]D<YF8^J8@S,G[*A-;NX +ML($Q,)#\T'[!(`<S,I1+H`_T0(&=X!"3L#<X/T*)H&C;,[IC+G:B20@9KO3C +M.$B&G.T\=DA`W"(@;9A`.YSA,[#2/H%(X2?D90M:)(C$_9`+#C]4=Q1J4M(J +M-`-1H>,S@[)F$MJ-J`!VGAPWA27ES7N7,\^IJ%,0T1L-X_5!`P-`,C!_5.(X +M&R>!`<4Y:-.HC?*`($[3E-$$1RB($8R)[*ST9]K1ZE;U[VV-S;,>#4HM=H+V +MSD3PH*PS.,A,YQU2[C`^%/<FD^ZJOH4C3IN<2QDSH$X$\X43J<F.(^R``T$8 +M(F=DP',<J0T26X!_R3FF2XC(X$E4"TPXB`0<2DW$1D1OS",L(=Q[%,6$^HN` +M^2H&$1./ND^`8&>^488=,EPC@S"8@#5(:<1GA`+FM!'O[I-TD=C\I.:#_4`# +MV1A@+8)&_=4"($<HZ+A3J:NV1'?A,QD"-6Z=S&B(<!B4`AH.2[)RFD2?43]$ +M>EHD:D_E,`:2_A-@&'W/=%&29.W?=/Y;/\8']T!#)F3"!L<D[[J:W>:-9KQ\ +MSV0!LMEDCZH(PX3LH=/6OPTZ[2T4Z%=X#L`2?9=IUR_I4^CU"QP&L0#*^?>G +MWE:U>'TW?E[+;/BB[KT!2=4,;+RY^&WIZL/++_9TW2GBKU\O)D:H_5>B]*IB +M&,#3``@RO-/`G\VY%0Y)S\Y"]0Z,"6,Q&Q7/.:X8SR]KMU'0V::;<[?JNBL6 +MRT`F,<K$Z.STMG.%OV`P#N3NL$7;8`&(5^V&`Z?H%4H,]0,>Q]U?MP<3\J-1 +M98(`D0K-%IB95<$@YV'Z*:@\GX^4VU%VB,`JU1C"K6WJ`5IK0`,J5J+`VU9" +M:I4`:/5!0EVD8^RS[^X+=7J@!2J'J-Q!/JQLLXU2Z<SF=T%U<&H^)4=!QUP= +ME!8:TDP"9^59H4G:<R5'0;)!!]U=I#/;W[*:78K2E+CQ')6A;TAJ$`3ONHK> +MGD3E7Z%)P:.<YA61+4E&D&R>RL460)A-2!=@8PK%(-@3\0M*DIB`TR,J2F`7 +M)`!V&P2G9^;M"HL4Q(]E-3$-Q^JBIG/]E/3$C/PMQ*"KANP,JNX'=6ZC-\J( +MLA^)"595>G3#B<"$]6D"V8E3,`#\B/=/6(`(^JFFMLRM1R8$86;U"WD'`6S6 +M[XB%1O=);@;KG9'25S;J.BX@C8K4L-#F`1E5NHTAKU-$'=*SJ^7$F5QZKI9N +M+US2U<1"JW3A3IND20,*=]VSRSZA*PNMW^#DB>)2UF1G]6K&I<Z`5K^'*9#! +M(^JP++57N)W!.ZZKI+0RFULS&%,>TRZ:U'#!S")X!&-^R"BZ![E2O`^(79R0 +M5&&9(QW4%1F8C'=6G-QOME05)F`JE5JK`!@&53>S)5^O.D\*K4VF=E44JS-! +M)5"\!+<8E:=U!DA4;B#@G)4VU&749)(GC*S[VE`+8,E;%8-!D$*A=AIU1OOE +M-*YZ[IN;4)B.,*`@;[$\K3O!/ITX69=L]4@^\*QJS:.JXND$<*M5T@1"FDD^ +M^RCN"-)!&58Y933*ZBZ).^E85R]KJL-'J&5O=3PUTD?*PJ[8?M))PY,JXKMC +M6+:6(B),*OU*\++=[FGU.!!,*%U;2T,&_99_7*[OX9P$1&4PIE&+;UA5Z\V? +M5Z^WNO:_P_I>784_3!(F>Z\2\)M?<]>:3_34X^B]Y\*L?3Z6QH&-*].$_D\W +MFO#3?<L#R'-,C!A-_%4_\)5.L[^:['*'5[+W/%M\35H#B2#CE5JH!XF%8K1) +M@P%`^`X:_4#N`N;VHG$Z"T_E&0/=`?B92?ZC[#8)H..(,[H&V!E)H`/_`'3O +M:00!VF4P&0$");DP!/Z)B"6@QCO*)^<F7$<RA<XP`0"`H&W.HDRG!`9G&(W3 +MD@DN``D[#9(P)VGYA4)H]4B8Y$H@.QVW3-,[`RB$'!*!M(T@YG:2FG$2?E$T +M8[I%IT$D2$#;@0XR1E(8&'9.$FP.9]TG;",>T)0YTD[X]D`&X+D0@-$B?HA. +M1(R@=C?<P<I">2-LE-Q,0@:=.YQ\(">WW3`Z<R92CTS'SA(9.1L@+4Z!)3!Q +MU'8)W`$`C*1#7-)_+`^Z@$O=J,.,)M9<6R2F,S(28UKJ@:7:9_J*JB#G`G(P +MF!=@G<I#!P9,[IB1VE`@2#P.,)VN,&2,8RE(G_-,T2=(]1C;=0*?3G;X1AQ. +M&D1*!PSP([E*??Z*B1I,C&R<ENG!!GW0-!:S43B8W3P)B1!4!`D`GO\`5,\G +M5G)XDI2.\`>Z1D@095(4F/68E(NA^_QE+20(SG8]D[A#@`\N`R3L@=CM.'-D +M1M*$.,'3NF:`1C]24I]1C"B#IG`](GY4M!H\P0/U45,8!G92VT>:-P)RBQZ) +M^'E.&LU8C$_9>H]$;AITXP%YK^'%+66DN:.TGE>G]$IP]LU&G"\7EFZZ1U71 +M_P#EMF8XA;MF8`GY6)TMHAI6W:-,`X^JYUN-*UG`S&ZOT(`ET_'94K1I(GZ* +MVP:>2HTG)D8)D[*2T$B!^ZAI9V<KUHP'.!\HU%RS8("L#;V_=16\-`SPC+PT +M079[J:VJ*\J:)D\+&ZA<:I;B>5<ZE6'JTG*Q[DDN)/*R!8XET'\OPK=O3U.S +M\JI2@>TJ]9MDC8B4T;7+1AU?FPKE$MF9D[95>@P`[1"O6H$[X*?\6+-J#J#B +MM*W`(`GW5&DX-P#*O4*@:!ZLA6"Q2;Z"1]DS"2^",;RDVLTX$2I&:"Z9&RTL +M'2,84[#J(,`2HZ6DN$?=3!XF`=D@D8R/ZL`*1CHV.V84#*ITZ<;J1KLC:2M" +M<.PF$%V^/=1.?I^4[*D"<*[-)7QI)D;J*KZA&)3O?)F,)M33)4%2L#JSG*HW +M^)P%H5R-EGWC06F2L9-XL;J-32#E8ES=Z'D-,0M?K`Q`.>"N=NZ9+BX$X7#) +MZ<$M:^/DDZ\]ED7]TZK5#9QLFO2]F!RJUI2<ZM,<_=0L=%T"D"QN`)72=/;I +M8,+$Z*P-IMANVZW[0[?"UBXY+=`$NF,*R6:LGLH+8^KG*M2"(E=,7.H'M(DA +M0/$YB%9K8!C*K$R2(SRM(AJ06D'M]E3K`D?*N/@XE05&C/8<H,^X(F#B%3N6 +MMTDM_17;QH@F=\`E4:\G!/'=*U%.LT#X&%2N\B>>`KU;_P"["S[P2^`?JC3. +MKB7$[$9^JH7%,:'<DK2N6@`DJC<B!$ITK+>0UY]E!5?+C[*6[:0XF8$K/JO` +M>?4<JLW$-Z&$96)U!HF)^/=:]T\%N3@+&ZD[USJQ]T^//E-51KO`>0[A8OB> +MX:*+@2&X[9`6G6,N=J<X97,^*;@.+QJ)SF5OQSEFM/\`"JFRKUD.=!@_W"]X +MLGLH=+9IWT_V7A?X1@#J`<7""<#[+V,UGML(.T?9>GPS^3Q>>HJUZSS734C* +M'^-I_P#R+!N6N-=YU')[H-#O\7ZKW/*^7:WY@V`3['=5J[8)])'"M7`!)*KU +M-);.?A<'N5WD;<E#I&Y'V1G)W.$Q(TX)^J@"0';?0I$X+I(G$)P`1F04SVN` +MQA`&HDXF$^II$"?JB(`=.1^J8P3OCW0(E@,M)]TL:I((!2(!Q'WQ*38`,EWT +M*0.TMP&X]T[B`,Q.R=L;[RF@3B539PZ/C9(N]\;0FV.GNDYHWV0+$2#OA*I& +MF2A`$P#$(J[FOJ:F-#1VW40AI#07&(]DB0YL`3R7<I?U>K./A,YIX./A#H+0 +M"(V^4B2T07$CLG@1G<;82<UIYD(I'8P=T(@1+D\#/JE,6R>ZH(")@X3.+=)W +M)3_T[(7-,?FQLH%)$PF$\$%/I($2DSG2=MT#`NDG5D^Z6VQ`QLD0>=NR$P!W +M^J51$_U2,\2GI5#3,M,&(D'9`UH.Z<@!`MR8.V8)2/M@]DT`'O\`!2`$D;_* +M!QN<A.`(()CX30=P0B:#J.HH'+=X.R;8C$_">,Q&0DYL8@;;('#LG`@IHSF` +M/A.1C:#O@H3ODX0$T8P`4B)$:1/>4FMS,.A)S9=@[(@F2/\`)3V7_/;C"@`X +M*L].$5`,CX18]'\`:139(X7IW0A(;"\R\`L,,#B97J?06AM-N%X?)/Y.N^'5 +M=+@-:3QNMRR`+1DQ&%B=*@M&(6Y:B",;K%:C3MP/+YV5BGAH[2H+0"/[J<8? +M"RTEI.@C'*T+,`JE2:(SLKE"&MW1J+3<`DE5KNL`(!QV2K5@&F52N*FL0TY4 +M$-R^2294%>JPT@UM.'3.N=PFNW$-,G94PYSZ@RB=K5`-DP9/*O6T-V!PJ-!N +MD@;*4U-.2Y1J1KTZK0T$NA2_Q8#0)(GNN;K]2T#33,RL^ZO+UP])(:<[)MOU +MUV[=G463ET0IJ?4Z9P'97FU"^NGW'EZX.RZ+IM"Y>`XN*;OX6W&?77TK]D@Z +ML0K=&^8X8=E<U_!5A3U:R.52_B;BC7(!)"F5N/:XW'+IZ!97$M!+E<I%AR25 +MP=GUBJP`..GY6]TGJK7#-3]5<<I6K@Z$C`@!."X9;((4%O=TWM$'=66%I_JE +M=8Y]&U.)R3E&S:$P`W)1@8C.%-&PAP)_,F<^.4SF&)&%&1!&5`U0^J95.]!+ +M294URYPG*KU'@CU'/99JQC]3I%TD;K%KTR)&)*W[_208"Q;W!)W]ESR=<:RK +MVAJ'PH[:AIJ`E77Y:3*%C0'3N5AO:[T^`0MRR/I$\+$LL'?"V+(@D$'A:CG6 +MI:C$85AS@UN`%6M.8(]RIJH],S"W&$55QR=E`70"#N5)4V)!5>JTB3,%79H% +M5\'A1/<'#(^O">J8YG]E!DDPJF@5@'-@B0J=S3GLKSF0"3^BJ5ORF/W6NS;+ +MNF.DPJ%<<1E:=WALK-KCU?KA--13N&!X^%F7Q@XV'ZK6K2LV\``D@(LK)O2W +M<A9%T(<2!CNMB_:",+)OB6@I9LM9]S5()@0LV_?J)$3W5^ZRPZL`<+(O'#6[ +M,]HX68XY,SJ3RQCO+S\C9<;XCJ@U<Q._^\+INN5Z8:0V,\E<5URO-0EIF#E> +MCQSEQSZ=W^"[7/ZJTN_5>N=>J"E99($!>-?@<[5>NK:X`"]!\47HJ4"P/]EZ +MO!/Y5X/U%Y57]0I%Y))W3?Q]+N5GTM)I@D$HH9V*[^S$E?/=RQH&.>.RK/TD +MF6\<*U6>X$_E^55KETB2`2N3U(@!JDX"&-1_9)Y)=O\`5($ENXQPB&<T9C/U +M0F=/?W1N)`$D9V0:N1PJ&`,;_JGQ(/"=CRUI(`AV"#E,QS2!'?9#9CET9/LB +MTZ1L1\*2N^B7@TJ98`T3J=.>3L.4S3+0[3M]D`P9V/T2$P2EK)))W]BF:X:C +MG`0/EISRFV/*69$[#ND2,`2BF&<@Q*0!W,E$8G/Z)AC9N_,H&VD$2-X3-ATY +M._=$8,<?)3:1N9@\DX4"&WMW"9TS.93M@DC8(G$`?"HB^=BCHN+'!['9;D'L +MG<1/I!CLFY)@XX0/4<ZI5<][M3GYE#'L,(RYI,B"0$VIH,Y01P7/P9/LD#P? +ME.^!$RWL4(TSOO[IH.<QD3RF'<D$I2#B-T[2'`P<CA129G)A"=AV1-(C3CV* +M3O*X)_U5`-WA/!!W"3@`2)3P)WXR@<`#U#CND#!S]D0PZ&_E&Z0WWV[J(;?M +M\IR(>,[^Z4,F&X!Q\)W@#TDS'(0,R(W@^Z3BX^WR4WHT[_3**6EH&G(Y!.55 +M$2#$-(')W09`AN?=)L3))QC9.<&<91#AW$X"N]*@U@=PJ;6D@$`1W6GTND&D +M.QE9H]`_#_-8`#CE>J=`TEC,%>5?A\0;IC2['*]7Z""UC>5X\_[.KING;@<+ +M?M22T2L/I>X&WRMVT:-(GCA<ZW%VW.!A6*8+G0H:(!SL%;MF@0866XLT&0P< +MJ1QTB04-(#Y$(+AP!@%*H:SS!(*KO=IR8E%4<#Z95>X(#42JUV^7$3A16U,% +MP=ND]NNI`,@*8Z:5/=-$A[BJ*3,X7->)/$C+)CB7[<)>*^JTZ-LXO>`!LO)/ +M$G6!>W[J;JI%.=X6+;O4>KQ>/?->A>'_`!11N+R7/G,1_L+L_P"-H5K::?(7 +M@5O6I4&MJ4ZI#VKL?#_BNG2L]-:H!A;PMG%<O-XK>8V/$76V],OA5J&&3NM[ +MH/XA].9;-#Z[!`Y*\:_$7Q"WJ5?RJ#O2WGNN0;<U!@//W5F][CI/TTRQGMV^ +MIJ'XAV%W6;;4:S7N=L`5UO0;47E`5WMW7R1^'O5FV/B*E5K/].Q/9?6'X<]< +ML[GIM)K:C2(WE+;E=9.'E\7[7]6A?='!;+1E46V]S:O],D+L:9I5&#U`SV*! +M]A3JR"``LWQ_@P\UCGK+JSZ9#7DA;O3>JLJ0-2IW'A[S:T4P/E4K_I%[TT"H +M#+0?=3^6/;M,\<G7T+AKA((A6:;Q&XA<7T[J;F0UYCY*W++J#:@`:X'X.RZ3 +M*5FXZ;3].GB56JF780,K2,$''=.XDB1"5-:15!J:>ZJW+0`3*GJ.TD@G"AKP +MYF%C8RKQYU0`LR\;(,B/=:MY3AI)P%DW67;[_HL5O%2TG5$?5/I/,(B3&-^Z +M"8=!^ZQIO:S0QMN%J]/.`0<E8]%P)Q@E:O3#!]E6:VK-WLIZ@!$E5:#HCD'L +MIG.B"MQD#Q!.57K&3A2UG3,*"I).TJJK5"2["'28D[*7TAV<E`YPV_NM1FHG +M.)&^_NJU?(CA3U7>G.55NG#20`M(IW+001NLZLT`GM[J[7<1,*C=.,F/T15. +MY=!,RLZ_@L)!A7;DDM67=O=M,@H,^NTQ(*R;W+HB/A:5Y4`$;$+*NZX)))D* +MEJA?._EF<!8M^ZF&;Y&X"UKYS7,W'U7-=4J$^81$#<K.OPY=L#Q!7,.8'3V( +M)"X^_+JI?.0<96OU^L#4>`[/"PJCCHYEQR5Z_'-.'DKT7\'!Y5HXC[_5=3UI +MI>#J)$9PLK\+K`T^@,K3EXG]5<ZS<^LM8X%TP0%Z/#.-O!YN<DEO3;Y+<\*3 +MRQW5>E5'EC40"B\UG<+>DV\%N7;-('IDY"IU6'))&#RKE8>C42T@=U4KQ,<3 +M*YO6@)B1B"F<P`'41V1.T@X(S,SPA(!F2)'=$H`)@#8<IG[_`"C'Y2.^R&`2 +M8B/<HH'!LB`?A$S0:<:I)X[)$>KO"36@/@=OE4.\$'26P0<@J>G7;3MRQE*G +M+CE[A)^D[*`-`)./F=D0D-@$`(&`],DC!2(;J<B:T?$)B,[1]4#5(:[(V3$# +M223'PDX;(@R8:(S(W4`B08#1(_1,_#>_`1%HG83O*8-$@$?7V0T89:?G,)X( +M,C'9,1C';=2.CR\B%0,Z6D#&K=)Y=`U2G#89,?FV/=(M$80,9)B4(:?>$^B1 +M@0$;8TF9S[H!#009"8-_I.(1N:(=F$+FD@#4<\H&<P1!S'NHB(=)^REJ.&F` +M[[('#83'*B@<(.^R1!=DF.,(R"'&9@]BG8T%QU:BT;P@%H+=."/A-^5^[H[J +M2&D$"?JA=$S'TA`TR?S"#WX1%S2(@`]^Z%D1S*8;Q.P0&#Z3D"<)-TDDDXW[ +MI/:)P<;Y1.:0R2[=$"V1L[8X2))F#+DW!.K=.T`.W/T[H'@D3(2`)D<$)JAU +M$Z73/!2:-,912CU8'^^Z/2(@B#V*`CTET@'@#E$,G5JB"J@K=LU/\UT%C1_D +MM,0.%B]/:75=/?E=3:TW"T)(PW("YY5J1T'@`?\`JVM$"<97KG1)\IN,PO(O +M`LBZG'SVW7KO0/\`EM)7ES_LVZ?I@@#/ZK;M1L9C&Y6/TULM!F%LV[8;.KA< +MJW%ZCF<J_0;GD^TK/H`F#(RM.S;@9E9;2%Q#-B%4J23)5FJ[$;0H'9$'"NC: +M%Q!R!LJEVZ9$[JQ<``0%4=)))2I"I-@:MH69XEZBRUMW0[*L]1O!0HDD@0O. +M_%M]<]1N#:VY)DY/99SRF,>CQ>/VKCO'WB&XN*[F4G'1/=<5_P"H=4)=J))^ +MB]1;X)-2B:M7+CG*Q;OPH^WNH#-0!Y*S/),7T,)CU'-65.N6B7[9C=/=U"PP +MYQ`[%=)5Z=</=HT&6M$``<*.MX4O:C"]M$GY*D\D^MZD<9=/<XZI,'&^ZJ5- +M1$SD;KL7>$KL/=J88!'U4'4/#%U;VVMU+*Z8^6.>>,_+D[>L^G4EKB,[KN/` +M7C_J'0WL8Y[WT@-B<A<;5I:7DZ1`*C:)$?7==;)DX98_*^EO#7XT6!#65ZP8 +MZ/ZCA=WX?_$WI=X6M;=TSJ'^(?YKXQ:7LR.V#W5SIW4;FVJ"K3K5&Z#OJ(4] +M;.JX7]/C>GZ`>&NKVUZR6O!'L5J]0H"[MM+&APXY7R9^%GXM_P`$&6_4*NGC +M43@[^Z^A/!7C_I'4K&F]M]2!C(UC_-7'/?%>?/QY8)NI]*+=1##J"S)KV57) +MP/==1<=2L[QYJ4GM+3[[K!ZZ^@X$-<TGY6+X_L,?+9PL]/ZH*@$.RM6C<AXC +M5MA<&XUK5WG-=Z>ZV.C]4%0:=0D?JL[LXKO-7F.ANJG:%&:GIR1\JLVL'4HE +M`:@.)]E*:*\+3.HX65=,TM*T*YEL<*A=G$AWT6:D4:DM)(Q[*"H\`8E'<.WQ +MD*M4J0V94;3T7CS/E;72WN(#L^ZY^W?_`#-UN])&IN^R%;5&IM`^ZD+B<'Z* +M*W`@2,J5Q:<R%4@'1F/^R@N'%H($J4D..\*"JZ'9=ONM0JMYD/DF4!?ZIVG= +M$\"<"`@=I@P<JQFHZCH:"3OPJM=V5-7C^DX/=5:T8$_Y%:16K'(RJ-V\3\*W +M7=B"0,K.OW`M(!$HBE=U0V<Q&ZRKZN`XD#=6[Z9)+C)Y61?O+FNC_LK%4.H5 +M]6RS;EY,Y)"N5PTSWE9]\XMIEJM8M9G4[EM.1J]BN3\17H-+TC2)S!6WU60! +MDX).2N.Z[>.8[:`PG(S*N$Y2ZDX875GDO<"9Y`5*@WS;UM!LET]X*>^KN=4E +MHEP)VPM#\.;=USXIIO$PS,_0KU7C';S7F[>R^&Z!LO#5*B['IR5A=4JL-P7& +M)GX6_P!8J.IV082`(Y7%=0JDDN(F-EZO%CK&1\_+^657V=2H!L2?NG_XE0_Q +M?JN6>^7DR<^Z;6>Y^ZZZ:]8X2X9',G;<JK6:7$RT;8"T[H>2#Z!K/YIV'^:J +M5:[)E[6O`P1IC[+S/4H5`X"=B@:(SOPK3G-8QX:^6NSIC*KD@B>WZ(!J%SW% +M[@.V/]^R",_F@SO*DC;4=QE"6AQ!(^@4`$&`"?@=D_IW=O\`*<S$D;93;'V/ +MU5!@!T^G_1(M!RUV)(]T-/)B?U1,(0L,"=X`GW3M$&3M[I/<"^-(`X`3O:0= +M+I!!RWE#02-+CS'9,"X8.W9$TM!!+2?JGJ5-1+G'/=%`!IW$RA?!='T4D>DD +M"4QT<S@930$3L"9&R,MD#@./.R8:"8[[IHT8RF@XGD;X2SJ`)."B8!&3PB+1 +MJS.1B4T@0SW/V3B0=XX12)TI@[!$H(W[\DE)[B223]E(`#."/=`\N`TF.\HH +M,:M\$H07$0<A.';<G9)D8!X13.U9V^J<.#1C20?NBT@R)`"8P0`<'NH@2XAT +M-/\`9(O!.70GX!D&>83>K,"1\H&:]P)(P"$W!).4^\"82()$3@I5.3@9D'A% +M4)D&2!P/[H&M`=C[IVN,^HC!W1#28QGX^48)W:0.P3:0,@X3L#9&H2#P#'ZJ +M@8(=)@E.Q[PSRPYL.()!'(_[I&(Q$#&R1$G3C3V"@)@)D'2"9WY^J1!Q(]Y' +MPF`Y..Z<CU`MB"9@H-'H30ZX)+=PNF+'MHC2L;PE0\VKS/M]5T=>GI:!N3L. +MRXY]MQ>\#S_&R-H7K_0!#6#;"\B\$M#;_3.)V^B]=\/D:6CLN&?:NKZ61H$# +M$+6MB2(_99'33D"`?JMBS:/3&WNN5;C2M&@C;]%HT@UK?=4[6=H5@XGWX4;. +M\->\F<=D-=H&>>45(-&\R%#?/`9RFH6JE5TO+0=E!5.AA<?U4X#34))^JQ/$ +M]\*%`M!S\J6Z;PQW7.^-NJ$%U.CDS$?9#X/Z4W4;FHSU.S^Z;H/2JO4KXUZC +M26S*Z\VC*%`4Z8V[+S[W=U[Y)C/6*%VVF&>6P?943TEMR\D#=;=G85:]3;=; +M-KTSRHD9"7^79N8].:Z3X48^MYCV8/9=E;^#;+^!DDZHSA6*#&TFB!GNIA=7 +M'_*\PZ2NF,QCCE<KU7']0\.T&U7`-!,[KA_Q&Z>*'3W,IXC$KV2YL:CJ+WR` +M<8*Y'Q7T(WC7`M)XPLWCITPRW>7R]U2VT5G`;?XEDUFAH&73)7K7BKP15I7! +M=3:8G:%Q_4/#-Y2.H4G.S!PNF'FDXKV98XYSAR]-Q>T3.,J1N@X!,QNM"YZ3 +M5MVZGTG"/LLRK2J-,220N\RF73SY>*PJC@&2''.)'T6MT+Q'U+IM1AM;VJS$ +MEH<8^RQ'3N1'M$)WD:,8'9:NJY^M>P^&?QDO;6W#+ISW$#=I/WW6YTK\7&W_ +M`%1E#4X,.[G'_5>!!Y`#I$D3(&ZEMKFI2>"UV1V*SZZG%<_VL+\?973>HV_4 +M>EC0YI,<+.I7KK._`+S&VZ\6\`?B(ZRMA2KU':F",G??W6[?^-FWEXTL<2'< +MA9\EEF[VY>/PY89:^/=^G7C*EN#KD0KC*HD1LN'\$]4-Q9M:7#@[_*ZNA4;I +MR5REVWE-+I=S,A5;P#08&/V1!YU3M*KWE26D?LCE5"[AI,;*@^H3G:.5+?U# +MF8*HEQ\S<%9K<7+,GS02<%=)TD^F`87/=+IEU0?JNGZ:`U@GG@++5:=-WIP4 +M-1QA,PB,[H*AR?=:VD(N[[%05W<3*3G9CA05'K4*%S\\QW*C>^!_JB,<S)5> +MX<!@G"U&*BKO.HSM[JI7J;F?U4M5Y,R#]51N'N&6XG?*J`JN`)^51NS&21]% +M-7>8D[G=9O4:@`,.CE61%;J#Y;`B?98M[6`:X=^2KMW7#3_=8O4:I>Z!WE;2 +MHJ[A$G8K(ZE5AKAJGOE7;IX;1(<[/>5SW6;EK6%PF7;DJ,=UG=;N@V3/I'9< +M5UJX#I@2"<-E;?7[II9`P`5QO5;B:CSK)/)7;";Y9SOQ1N:LO'IDCV7:?A/; +MG^.%PUD!HWWX*X>QMW7%ZRF&DS/&Z]L\*=(H]-Z*P-/K(EV9[_YKOK=F+R^3 +M+UQVGZ_?L<!3<<M^O9<CUV\ITNGN/G>H]QM_N5=\05A1N708U&%POBJZUO(! +M)R9A>SC%Y<,?:B_BJE3U^:&SPEY]3_YPJ%NXFBTM+H^`CEW=WV"Y>U_+U^D= +MGXR\-]/;3\QE,LJ'AIW7$]0Z8UCR((/*],ZXUUQU`TW?E'U4;NC6M>@T.'U7 +M.8UPGD]>WC]W1=1`U-)CF5"_2*8,[S(A>H=7\&"Z9_)<1&=ES]WX!OZ;=37A +MXY$;*;=9GC?KC3$("<SO*Z]OA"I3=_.!!(V*AN_"=<#71W/!57VCEB0!F<I2 +M#CGNKG4NG7-G4BM3<!W"J,;)+9`GNG#1SIU[X/=+T$-TM`(W=&Z?T>G&P[I, +MR<'[!4,79QQC9.(F7O,DIZE-["0]KFD\0F@3.<\(&!&0#)E,2.,RB:&YU`F= +MDTCL80(#G>$PTG`$0B@2E`T[01RH'I`!DDB>ZF)HFU`'IJ-,&,Z@?V4&S!P1 +MN40B<';.RH<@#'VSDHGZ0"21)0D@SEL>R9VEP`D;=T"D$$`1/NA><!H?,)P0 +M<')X3`$/,('80T;QE-<5"][JCX)=V$)8\N5&X@C`R/=`+LQ&D0B;#3L(GE"X +M#&1LF`':<**E!/&W*#5!+M2?<`2?9,6P"`<3L@0$\X3%N)B.(2]H'W2@MP8S +MVR@0`#`G@AA`&"A'[>Z378.<[9*!H)VPG$#!PD!P?NEIF3.RH36@8)!E2!H< +M,`F/=`W><%2-<6[8/SNH!:!D@$CY3:!S(/.$5327$M$#M,H#$D"3]4!M!([_ +M`*I])#])!!Y!3"-')?QV2+3.<(.H\&4PTS`&)(717=-C6^IO')6+X+HES0X+ +M<ZDUV@/.RX9]M1;\%TP+T$N$+UCH(_E-D$87E?@5A-ZQN"<KUKH;1Y;1,D+A +MEVTZ'IHV&J%N6#1@%8O3P0=]^ZVK!IQ$@=ESK<:UH,3(PIVRX`<*O0/V^5;H +M3IE1H4%C252N*PIU0_2UPWTNY5RZ=%,R8^%B7U:*AS"59-@OKEM.B7%WJ/9< +MK4I5NJ=3\O<3PKW5*[GU0P$$=UM>$[*G2?YM025RSYX>O#'TFVQTKHM'I_2Y +M;AP"IN:*M<ZFR"KW6+TN8VDQ^.<H^F6C0SS7%3+FZACQ-T_3K713D`2KF'&. +MW"JU;JG3)9J$!5+OJ]K;-U/JM[0L[TWVTG@-9`!D=D5&EJ."!]5P'B7\0K"R +M:[36:2/J?V7'W_XK=2)BQM2_$!SC_HF.6VYX<[-Q]!4*376Q:^X$Q.RSOXJQ +M94?2-1I=L25\U=1_$[Q@7.:ZN:378AK1_DI?"?CV\KWX9=522[NMY7C<A/TN +M7VO<.N6-I=UWFF`0=EC5/#=*H(\L$'V1]"ZD:U)KM0,A=/T<4[BHVF2/4N.U +MLN,>:^+/!U&I;.#*0'NT+R+Q)X9N;*LX%AB5]8=?Z53IT6N:X%K^.RX/Q+X< +MHW#S_+&<_"L]L:WXO+^7S1>652FZ/+/RH1:U0X^C=>T]7\$->\%M,#/`_P!% +M?Z1^'=@*7G/I^8Y@D-=^7]EUQ\UO&G3.X2;>"5:%2GAS7=LC*K.U,<=M)^Z] +MF_$;P>RM;:>FVK35:9FFWCM@+R:^M*E&X=2J4]+V&"'`@A>B>25QF,RFX73? +M56;F`<+T+HMK:LZ<7ZAJB?=>>VC8,!H!'NMNRZC4#6,U&!N)6<VKX[9.7M_X +M:W3C08V9PO1;![B!J.5Y)^$]VUP#>8WE>KV-352;F)"X8=/-Y>*O/?+("IW- +M0EN\2CK/AF<*G7<)SF5IYZI7U0P1.Z@MP7P3GV1WCB7'&$]AETD$_5*U&QTE +MD$%RZ*S_`"?V67TJB-`*UZ#2T`]ME%3,;Z!Q&Z"L1IV1>8,Y^?=15GG3GA6* +M@<<^RBJ[%&^I(Q$*M4<2[E6):=[X=&?E5JQ;$20B?4P2JUQ5):)@?"TQ45P\ +M]RJ55X;JER*XJ9+MRJ-P]V2#*H"ZK9*R>H59!`/W5B]K2>0LB^J03E:D9V@N +MZI#?4LN[<8)!W5BYJDR#.-EEW=:)DA7>F;RH=5N]!+3D+F>K7;7`AQU#D+6Z +MS6`$G\IW]ER75GZB'`B)5QA(RNNUAJ(#L@[^ZYVYESBX!IG`!5[JM8/J.:2" +M>\RJ=C1=5JZ&YU87IFI''+FNB_#OHW\5U-A<P1$_&Z]0ZC3=;64%T0(E8WX= +M=*=:6HK/;ZG#D*]XPOV,MRRI`G?*Z^#'=V\?GRW=.!\3]4TN>73O`=/^BXR\ +MN]=4OW,_HM#Q;<L-PX,?,GDK$IG^9G29Q*[9WG37CQU&K0)=2:X:A/9%![N3 +M6Y`HM!,?5'+>_P"JQMWY>K6W3!<.-2X>XU%H-Z;28T`-..96YTCI8-/43G=7 +M*]FUHPI:\#EZMI4;)8^?91:'-9_,9`_=;M>@T..<+/ZRP4[7,$\*;-;85:T_ +MC+OTLAE/<R@%FTUWAK9#$[>HNMP6MI2J5;K+V/-3RW#V"LARAZST6WNF%KV" +M7=PN(\0^%:UO4+[<2)VR?[+MZOB&B7#S*+E`_KMH]_\`,C3&Y"GK^'3'.QY7 +M6MW4ZNFH-)&(.$#6Z3(=MR%W/B2PZ=?,-2W+14W[+BKVVK6]8L<S8[PD_P!= +M\<YET9]6K4@/J/>!MJ,P@,EQ2+\>EH$)M3HB/]56B>-O5MV3AIQ!W33[!(., +M[!$V<9R8$>R4NT@H2XDF44D#;]478>9G?L40&-\?"',_ZHVF#,1[;H'8#ITB +M!_=)C!)`$^X3`N<Z`W/ZHV4JKGDMI.).ZB;@1,8@<(?ZL*=UO6:#+'`*!\ZH +M<"JNX8<QD'A`\2["?4T"8(E,]P(](,G=#87"!!'J2:V3$'/*=CF\@DI?U;%` +M0;'R$+@.\%&YS-,^W`0AS2W$_0*:-E3:/_Q#W3/(G@)PX#(D'YE`7!QW**9W +MN?LG.D-RGJ5`8@#TB)0:P3)X0/$@)0?@)]0G&R3BW$?H@-P;$S,I-.DB=O9` +M"W3$[;82U`YF(VP@>#J_*G<"3B#'NF+F@"<%$"W2<CY5#!H'])4E,'S(.!*C +M8YNTX4U)S-;9<`/=!V_@YH;:`[GN"M+J$:2"J7A,--C(``*L7[FMSJGA>:_V +M:G3:\!,+KO5F?=>J=$PUIC/LO./P\I:GDD;<KTSHX!(@B%QR[:=!8-#F#=;M +MBV6[!8UBW8@X"VK+`S]I7.MQH4&D-C!5JD1$QRJ=(G?5CW*G+@UO/U*C1NH. +MQIG98/53II.).5K/<ZH[=9'7ITZ=62=I6:Z^/'EA])HON;_(P#RNUITZ=M:# +MXW4'A'HU/RA6>-U9\0!M"F6@X"Y:O=>GVENHSF`UKD.X'"N]6ZK3LK')&`L2 +MCU!E%I).W*X?\1O$%9[#3H.=]%-Z;F'M4WBGQZRA4>RD[4Z8@'_1<9U#K_6. +MK.TAYIM=V_[+.Z;;NNKXU*HF3RNCI6S:8V(Q]UC+6+V888RZ8M#HQJ.#J[I) +MXW72]'Z=;4:`UM#BW]$UG3!>T`\\!=1:VE(V>&B8F96,;<JWY<M33C>I=,H7 +M37%M(-DKF3T?^%ZH"#&<+OKRF*3W`-()Y7$>+;Q]"\:[8`Y*WC;T87EZ]^'] +MH;JFRD'0T-G==)U.>DO8\5</&/9>0^"/';+*BUKC!;B94OBWQ_5NS.LN<-HV +MA)-37USR\65R_P`>K'Q#Y\,K5AC:2KEM9U.HTP:,OC:,KYLNO%767534HEQY +MQ*[O\(OQ;%A<ML^L![6N(]2W,;]<O+X[C/XO3[FS-$^5<42UW8A36%"DRF0X +M@`]U<ZUXCZ-UGIC*MK7HOJDRTL()`6795]>IIX4RGK7+&^^/*+J-K0\Y^FG@ +M\B%Y'^+'A9U6[-]0HQK)+H$?V7LKP"X&"8[Y5#Q#T^E>6I:Y@)`X"U,JL_AE +MN/ERM;NH5M&W&$SG%A!'!7:?B%X?-A>NK"GAQ.RXVY&C):"?NNN%]GJLFMQZ +M3^#MVYU4#)(`PO;.E5?Y`)'"\)_!>/XDQOC9>Y=.`%N.#"QCW7A_4]IKFL9P +MJWFD.)F92KDZL$2H8=&ZUIY052Y[HTX'<J[TJB9'(/"JL`+S(6OTEA=&F%+R +MU&QTVD6P3VX5]N)B3"BM!I8./JCJ')`D(L)SA\A5ZSW.$94PES<E07$`Y5@B +M+AM*KU7[G.5)4(C4#E5JAF3*K-15'G3NJU9\C.?E2U'B#PJ-T=M)*L9J"O4. +MHJG<U1!X5BN]K1G'O*SKVL)QL5J1*K7E3<+)NGSL=U9N*AEPX'*S;JIZG9$+ +M<9M4KUQ;,;+%OZT.,DRM.]?.`?N5A]5J,:TESC[*5F,?J]P\M@@QRN8Z_6;2 +MID`DK<O[F9,;#>5R'B"OYM<Z<&5UPG*Y<,BLYKZAF)/*Z#\/>E5+SJC2&RS< +MF5D6W3:CR):<G=>N_A;T5MOTQM0@A[ARNEN^(XYSUFZZBUMJ=I8-)(V7EGXM +M]3+'FFS(G/9>D^)KC^$L'DO&.Z\$\?=1-UU%X#@9*]N$]<=O!)[YN?KU75GE +MSC]$]#)AT.4#!!)@94]`MU`M])YDKGMZHV+=H\AL=NZ/2/=!;$B@T3PCU.[_ +M`**.D?45M0T4Q&,*/J-.*1(.0K]-N(4?4*8-J9WA9KP1S=.F*E4DF0J/6;8U +M(80(6U:V\`F/=4[JWKOJDM<T#X5HY>O8-&/+6)U:TA[FL!E==?VEQ@4W>HGZ +M*B[H]:"?,:2<J[9U8XFO8F"33#C[=U4JV&J"VWJ./,-PNZ_X34UD/=3(`[*I +M?V[Z3'4F:)(_I!E7AKVTX6XM'3Z:+A\"52O;'63K9QRNO=;>HSF3F6_Z*K6L +M2]^DAHWB$TU,G$U^E,V#=NRIW'3:@P&Q'.<KN:G209`U$A5Z_399#HD8W33I +M[N#JV]6G+G-/91D8,@CV7:U>E-."R6QA4KCH#:KCY8R3QNHU[1S5O;5*];12 +M:7$]EOV'ABYJTVNJ,/\`DNU\%>'+6SH.?5HZZIYA=*;5M8M92HD1R,*V:<KY +M?P\YI>#GZ-;F&&Y(!2H^'Z#20:1WB)S^Z],N[#RK1VH9/SE5K'IE%C-3F^LP +MI$][]<YT#H/3"]K'6GU)*ZRT\,]/`&FB,J3IEL&WD1$8E=)1I!N,1&W9,F)= +MUSQ\,=/J`M?;-CZK+ZQX!Z7<L,4-+CF05W(9$@#*;RR?21G98;FX\0\2?AY7 +MM230!>W<>RXWJ'2+RT>0^BX#.87U`^R;4'J:"L3Q#X5M+NB6FD,[8Y3==,<_ +ME?-;VEIS@;Y0$D#!F>R](\9^`JM#55MFN,3L"8"\^O+2M;5C3JM<TCN%9DZ2 +MR]`+2&X>'2.%$Z0<'Z(BT#(G[)B,SJ)^55"X&9+OT3C3J.N8CC>4[L`2XSW" +M"#/O/952@SB)2(.=@"EDDP=N2E!F"5-!S&H$'YGNDXX@"`G,$C(R4H,Y('8( +M&D:<8*6(.<!.0-(,C/"8`C,-A`[M0EID>R9L`?F$)5!)&!\)RXN`DM$"!"&B +M)VV4U#);)D_"KM!QLIK=L.;)[0@[[PN\LL8+1D0K5;0^L`=_94O#CW"PV`(" +MOV-(FZ$B<KSWMJ1V_@:CHI-.,Q*[_HU.3Q(7(^&;;R[9I;'==IT%I)!WG=>? +MMJ.AZ:,`&/JM>U$#(!]UG63)B``5J6W&%ATBW2$-DQ*BKO!@$A$ZH6L,B<[* +MM2FK7C@<)5BU1IC27'D;KG>M5F_\0#?Z6E=)>'R+0_\`V]UP?6;E[KXEN=., +M+.7$>KPX[=M9=5HT;)H:1JB-UG]2O/XPD`R5SEK6K5G`$D#Y6WTNAL9RIOV; +MN/HJOZ:Y[#C#ED7WAAE4Z],'.05VM-@TQ"<T6:9@9"OI*Y_N91Y77\-MLZVN +MG3@9G"HWS-+2US8/Q*]2O[:F]A!;L%Q_B7I#7-+Z8((,X7#R^.]Q[/TWGYUD +MP.E-+GAX$`+>I533`@[X61:L%$QI,K1H5-5.<_!7#"/5Y;LUX!4<97(>-.A" +M[I%U+<<+IKRLYK@!LJ3[C,O$3W6\;-[8FYT\O'2;NA<Z#J`"Z?H?1`ZBVK6> +M2#C*W+NE1J'4*<&9E2L#!18QQB<+>7DV[;W!6?1+048+`0<KFO%7AGUNN;6F +M6B3M*ZZA=0P4VF>)5_R`^U@P9R0ICDX7^-V\M\.^(NJ=!O12KU:A9.Q<5['X +M-\56W4J+7-JC5&1J7F'C?HYKZZC&Z2V<PN;\,=7O.D=5;3\UX;J$S*ZY8S*; +MC7KM]26EPVJV0<*VRDUX@E<;X$ZFV_Z?3J!Q)+05W/1]+HU''NN.-<?)CIP' +MXI](\RS?Z>"05X7UND:5RX"9E?47C^WI5>GN`'J((V7SCXUM'TNKN9W<?W77 +M&ZR;\-]L=.F_!JDYM0/)[?5>SVE0>0-UY?\`A+:Z;5K]($QO]%Z53=%./9;Q +M_+Q_J;R.J0XD\\H@TEL]E'1)>\S@?NK=)GNJ\RO0HN=5Q^RZ#I%#0T$B%1LZ +M4OGW6Q;"&QNI)^6MKU(C3[IB<2@&1GA)VV^$#/>0<%5[I^KE%7V@*K5<"2)C +MY5*&JXD$*O6=C*.K4$C.54N'DM*UME'<$`95*LXP7$XX4E=Y.Y52Y=#<A6<L +MJUW5ANDF?A9ES4()SRK-P\@N_NLZ[J``\>Q6XEJO<OP<CW67=5-),00IKVZ: +M`<B?8K-K5-1SLM6L(+BI+7%P``7/];K0,EO^BTNK5@QCX,_5<CUZ]TM=+IB4 +MDW5GY9O7;T-+F-W)[I>%^@UNI5#6<UVG>2L_IUN_J74FM@F#W7KWAFP%ITVF +MQS0T@!/)EZ_QC>$O]JY9WAUE*HQH8#GOLN\Z#:BUZ<R&_E;M*A%JVI7'>96G +M=N;0L]($$!=/T\W=O-^KSNM.%_%2_=2Z8\N]P#_L+P?J-P:UT]SA.>2O3/QA +MZPQSC0.'YDYRO*ZT$EPF">^Z^CGQ)'D\,[IPX:9C8Y$J6@X:MB1QE04CISG( +M4U$G8$D;KD[[:M&L/*;B,(_.:E0/\EOIX1R?\*;:?6]-LF..4/5`T6)(^(E3 +M`>O"BZL6_P`.&]S"S7AG;,MJ9-N9W*KW-,LIDD+5I4P:0T]E3ZE2.(Y*7LC$ +M;1+W&JX8]U'79`@">ZUC0B/A5G4QR$5C5K=[S$P-EEW5JW4=()DY*Z.ZHN/I +M`W45O92XN<`594L<Z_IX8UQT@GGG[JC6M@7D"F#$X"ZV_I,93(@#N0N?OG_S +M6L;!^%J7;-FF<+`5(B!.Z*MTBFYVD-(,296UTZWU09$QRIZK#J+6MGN4I.>7 +M*5^B:1E7?#GA^:HJ5J<P<"/A;K+=]2J)87-:03A;EG6ITP&BE$>VZFVN?K,; +M:.&&T84U&W=2;JV'*U_.81D0J]=XK.AC<`9*RK'=1?6JESR8&P'"(6S7'5L5 +MI.I:<D83,I2X''O[JIJ,RU8/XX`+HJ5!Q:#Q^JR*["VZ#N/W6_THM=3`SVE- +M<$%2M&.;*;^#@X&W"TK5D-@1'RH[JO3I#W66E;R&-9(C*I73J3<$H.I]2@$- +MQ"R;DUZX#FEQ)/"*+J%.A5U-(:00N"\;^#;2^I/JT`&O,YC"[BA87`>7/<2# +MPK(L6%N1/>5+(2V/F?Q!T:ZZ9<&G68=(Q,++R!!_5?1GBCPU9=2M7T:E(:\E +MKH&\?"\+\7=&K]'ZF^A581DQ@Y"2_*[XY>S'(+78^$,N$"20#LB,9,-2](=. +MX6V]@R9!.-TAZ20<@H\-<<80^GDJ!GD;MVE//!(^4G``CU2$B)/:!RJ'+70" +M!B,IMP9@GZH@,.]0CLF@`X(RH!9)SR$0+L@@;93M'NT)R`08*`#.W^JFMI;4 +M`/?91[GTCVGLI[8$UFD[R,RE'9=!J.;;MP(WRM[H=$U+QI(_J!/W6'X?IOKL +M`I@O($P,PNN\+VX_BV:A#@X#3O[KS^2M8NXZ-3BDQL8@0NOZ#3.(;(7,]-I_ +MECV76]`I;'(G9>:UN1OV3(;"T*8B3A4[1L08.(W5L;;_`"L5LUQ5TCYV1=+R +M^8&ZI7+R*D;B5<MG>30<\[*SMJ(O%%X*=$M#L[;KCG-%2H29"T>M7/\`$WD2 +M2`=Y]U'2IB=ESSNZ^AX<?6%TZC&\86W9PT<2JEA2(C]EI4Z8+06C;*8L^6I: +M#CJ$[>ZGJN`$3*@I@QOD(WCT223B5TCR54NH<9V!]UD=8`%)P.=X6U5I'1)[ +MK'ZO0<_N1"-8WEQ%_5-.[+'0!,J0NBC(.47BBR=3)<!)X/98_P#$5&MTF8B# +MV7BN/K;'U,,IGC+&E0BHZ=4S[*MU:V>'C0?S=UG'J8MZT-S`R"-E;/5VU'-< +M3'?W6'>8V78+BDZB1JW/"AJ5#(SC?"FO7F\IRPR&_<*G>-JMI8!!GA734_U- +M9OU5&Y]MUJMOBR*>'?!7/VCJK()'/V5FGY[7E^C$R=U>9TSG)>TO6'^8QYT@ +M3*X3Q'8-;4\YH#3JE=TYS7L=KXGZ+G/$S6N<"TG=;PRU3&?':_@W=/%G!,@1 +M$[[!>O>'#YC))7BGX4/\MI&"TD<?"]K\+$&BV(V"S)RX_J`^+@W^$/!SM\+P +M3\0:;*GB!C6B<P?NO=_&50?PS@#!*\2\16GF>)VG4YTNQ\RNF5TQ^G=K^']D +M*=BR!B`?V74D-C3MA9OA6CY5@P_].WT"U`S4[;`77#B/%Y;NI+2E+I/)W6C2 +MIPV4%E0),1]5<;3.T;>ZUVXGLVB<#"T[<"`)RJEM2@29@JVQS6CMP5`6N9$[ +M)B_?$H7GU$YRA=F/]PB[1UR""(S.ZK57"3D*6L8=`XE5;ATR`?[*I45PX<%4 +MZKY)"EN'&<'95:E4##HSR545[MXW!]QE4+BK(._,*:\=(D'?LLZZ<1SLM1$- +M=X$DG'*R[^J"QP`^JL75:6D?NL:[J$DMG'RM=,54N/4^2,;X56\K"G3($`_* +MENJ@8'.]BN=ZY?8(F.P":3M3\1=1\LG0<D0N.ZI=NN*WE@;G,*WUZ[<7RXDG +M/TRJ/1;*YNKD5-#BP$$PNLGK-M2>U]7>_A;T!FD7503,;_1>@/MJ;6P'8'9< +MIX,O!0H-IC@!='6N@ZEK!P5Y9=VV]O1EQ1VA:VY@GZRL7\4.N4NF])J.%0-< +M00T'X*H=8Z_3L:[YJB0"=_\`1>1_B=XG?UB[+!4FFTD8/N5]'])CJ7*OF?J? +MYY:C!Z_U*O?WKZI>XAQ,_$K-,$`R<=D(<2<G?W39,9]EVMW>222<)A!S$1[J +M2W$.S('N>5`S#Y))5BEE^J<!0:K':6ANO[)_,_ZRAI.)IM/MW12>WZJZ:T^N +MZ5P`_2[!E1=5J--:FTG!5VO;LJNEV"/U697LWU+\14):-@?E3?/+PZ:%%@T2 +M"J-PT.N''LM"V86TG`G8*"G2PXD*6<D4:S(DJE7#9U#9:UQ2!]BJ=2FT/,B< +M_1%4J5N7NSM*DKTFTV$#`.%:)8P>F>Y"J7+BYQ(!QL@Q^L-F2(CW7-R/XL@R +M#,1WRNCZXXMI'(F#PL7HEK1JW)J57$F<`;!:Q9R:?2K1SAD>DCLM!UJ&TPP9 +M)Y[*?IC=1\M@)^FRV[7IH%*7"7.4JSABVS&V].`V4KDT=.K+2MJM94J#2YX5 +M2C:-NJWJ9Z`5!B4Z=6M7`)=H!6E3%%K`QC8`WE;#K.C2ID,:-L*O4LV:,B"4 +M5EUF-VD(6-&DJ6[MW-?#23W4894:<Y[HJM=TX.<+:Z.T?PXU3[>ZS;H$L,XA +M:70P'4!WV*J+6IT0'!5ZM`.)+R8]U?%(D845R`QDQ/NIH8]]9TMW.`5FRL6> +M6W2,#"&HWS@2[8<*WTTZJ!#>$4%:U]`[JK5MXD8^%K.!B")Y45:GJ&`)4(Y_ +MJ-$-,F)',+S/\;^B-K]/;>TZ8ULG41]5ZQU>EI:0N5\6VS;OH-PQPDACL`9V +M6;TWC=5\W/;I,$B9Y0-(@AQCV5[K5NZAU"HPA^'$01PJ+V^H&<>RW.GH,?S` +MR/2A&6Y."G<T9]1CW3L9+9!V_54*`1!@F<%,]I!'WRD`(*(N+_S'`;`Y4"9@ +MDEH'9,9#R,&.Z<M;@ZYE,UH(_,&D($))&!"FKTZ;'!M.HVH"`Z0"(/8_"B8R +M=C(]EUWX<>!^H>)KYHI,+*,P7P/\U+=08?0^BW74KHMMZ1<UHDQE37UDZUO! +M0<S0\8(/<%?4O@[P!T_HG074Z5(`Z,GDF%X+^+5B+;QC5#,`N)CZE8F5MTF- +MW4?A.C4#)!@#<@PN\\(VN14)!G<KDO"]G_(8=4!T`E>A^&[4-MVSN0O/Y+RZ +M3IO](8?,!P5VWA^A+`2,_LN4Z'3]07==$I!M`$`SN5QR;Q6Z3-.3A*X?Z8'* +M*J0%2NGR)#MEG;8*9UW')&Y5CK;W4.GD`XC*J].!=6U$\\H/&%8LM(#MQ&ZO +M4M;\>.\I&'9ESZI<3N>ZT;9A<X"%0Z6PZ0MRU8-$[+CV^E>(L6=(M'NKU)L& +M%6HZME<H`XX]EK_CSY#HTB'$Q\IZS0)QGA6J8]$(+BCZ9WG*Z:T\][47@EL$ +M2J56AK!!VC"T7T^9F<(6TAIR03^R:1R/B6Q-5FV!V7'7UJ:50M<"TSNO5;NT +M\T&`/DK#ZIT%CS,;K'DP]NG;P^;UXKS*^Z8*M,U&$XS'99CJ#V/($QL2.%Z+ +M6Z&6N=3@D$=U7'A-KGA^D_,KA<*^AA^KQDY<WT%M1M,`G<YGD+:LNE"N2X@^ +MK)"W+7H+*8$@86MT^R;3&G$RMX^+\O-Y/U/M>&%9^'62)IQRKI\.T6TSZ=^% +MNM9#X4PIE[<@CA;F$CC?)E?K@>J=`EITLW[!<5XDZ)=4*@<X%S9WS_DO<:MF +MPMG3)YPL3KO2*3V.+VM."5F^/['?Q_J;B\^\!:V513F(_39>Q>'+AM"RSVE> +M?=%Z0:5\1387$NG&5UEKYC6:#+2,0N,WOEZ/+E,X+Q1>.KL>&C2`"%P%C:ON +MO$)>[=KI_5=]U.AIZ<XXDCGX7.>'*&GJ+ZK@)G?ZJY3=C&.4QETZCI](4K=L +MB/3'Z*]:L+GB,RJE-X>0T;+9Z31)C"[O#GVOV-,-I@$94H:"XP8]U(U@#1,= +MT3609X*TY'8W2/\`-$^8C]T1<W3G!4<@SGX3I2,<G]4#WMCB4SB)[*O6>`"` +M,H%6JX.)5.L\03'ZHGN#N?DJK<56Z2B(KBH!/;]EGW575($;_HCNJS9)G?"S +M;JX`;@\PKH#=5B)$X`6=<U23B3WE'7KR<E4>HW#:=(P86Y&;=*_4:T&>RQKR +MY$$@?)"DO+K7))^ZQKZZ9)]7^15W^&-;#U.]`:>T&%RG6+AS@XD%L;$]E<ZK +M=M=K=J.!&ZPZ[JES6\NGZN)E;G'-:F-MU%$TVW=T*8&[@)]EZ!T2UM;#I0UA +MLEN9^%SUMX??;VPN2(.\^\(>I7]RZU-(/(XPLV^]FG2X>N*]:]491Z@[2,3M +M/NK'7?%3;7ISW`^K,"?9<97J&C3+G.)>>5S'B;J=2XJ>7K,-VDK>'BWEM/)Y +M)ZGZYU^ZO[FJ35(:02<K#>_5,YY.4QD&)^@,IG.$@-Q`7M^/%KD[8&0$[RQK +M@&O+\"3$0>R8`:9#OLA;^8`$F-U`='<XV'=3T##QNH&EI@@$"5/0_/B=UH:M +M(#RQ.Z*&]D%%H\IN"<;A'I'^%RJOLL@&J9V"IVK1_%/<),E77B0\S&-U7Z1^ +M=YW,K,>&I+B&MTX!*<TXI0,)5Z3S6EIE1W#KH`Z::G`K78@9[*C4C)G[E6+V +MG>53);I`506+R^:E0_"32AK/I@$:A.RI7-TQH(:`>_*T*EE2&3)/N50O*3=6 +MFFT0J.;ZW4N*N=`T9WRKG0K)CZ8].8RFZPUK7BGB5J>%J!=5;3`QW5B5O^&N +MF-ILUEGW6U492I,U&('"*U93MK8<+-ZC<&ZJ>32&.2I2(JC?XRX@1H!^ZOT; +M>C09@!!8VH8,1`W4M;TC3,E155[0ZH2!@*"Z:`PGG97"W0P[R51NG3,\JHS+ +MIH%6#GW3TZ>)`VRB<-50XDJQ18XMC^GV**HWUN#3EI(/96/#?J:6<C"?J\V[ +M=%5A:Z)`/94_#URX7;FAIR@Z,T_*&=EF=0>Y[M+0=,[K2%.K5:2_TM[*C?-# +M7P%"*XI#RH4?3JGDW9IDX)5ZFV:4++ZAJHW#7C8%%;=1P#9(5=M:GD$B5:Z6 +M^E=VW$J.[M:;7X_109?7'-\B8V'*YSJ`\RRJ0W)!X6]U\.;2ADD'NL^C95;J +MB:;&N<7!17A'COH-?S'W%*@2"XR0-\KC*E+2Z#+?HOIR\\-U*5!S*M#6'`_F +M;*\_\5_AN;FL:MHUM.<D`0!^BF].V.?&J\?C,DR$VD:1E=]<_AS?TR22"!M' +M_99MWX(ZE287"DYP'8+7LW,I^7)P-6P/MW2<!I@?57>H6%Q9U-->DYL<PJ;@ +M-]L;%6-!QK.>>45-OI=$']$0;(&?T75_AEX2K^(^LL9I(H`C4Z-PK>$WI9_" +MSP1=>).I-<ZG%NPC6[[+ZF\"^%;/H]A3H4:8:&`9"@\`^&;/HW3:="A2:T@1 +MA=93<R@WW[KE>>7*Y;1=5IM9TU^G,-*^4?Q?/F^-JH@8,9XR5]5>(;@CH]4, +MSZ297R=XOHU*WC"NYY!)J']UCZZ>.-?PI2.BFTNYE>A].IM%```+C_!EK+VQ +M]EW=M3`8T2%PR[=&QX;I@U@/<;+M;4BG2:-H"YGPQ;RX'3]ET55NEH`Q\KCD +MZXP=>I+`%3O'@-V$]RIFN&C:52O8\P;JQ?J[T:FXF=_W5#QDX:6,`,DP95RT +MK&A;:R`/JL._KNONH`?TM]UG.ZFGJ_3X;RVGZ91@-$'LMJTMB0(V5/IU+T@Q +M_9;MDP!@$+GC-O7G=!HTM+L[^RN4:)<V3QW293&J0(5NA3C<+I(\V5/0I@LV +MDCE%6;#/RSP%+1(:T>Z50R#Q[+;A8S7L()0O:3!.`K5>GG=,&R,$I$JN:+8] +M2J7K&M.`K]P2,;\3*H/IFH\N!='*;28LZM;ZG!WU1"FW#2-NRO5J$"&E1>3[ +M&=U-JJ5*#29`,<J*JW20&E7GL)$94;+<N<)G=2UN0-"E+`1O\J>FPATDJQ0M +MM+,C[IZM/&\=D`Z`:9(^JSNJ4QY1['=6*M=P<03$+,ZM<GR2)5M;QQJY^'=[ +MTJTZA5IWIHL>?R/JQ&ZTO$PZ?==8\[ISF.9I&HTXTS*\RZK6)J:P3*Z3PG?A +MMMH>^2=LKA<I?XZ>C]OUOOM9\37&FEY;")VA9W1[5P`>`02K5S2==W9=F`M+ +MI]O``(Q*J9743=,M"\@E=%84`T"1@*M8T=#0(6C1EL#=:CRV[$`V8C"*DW.> +M43&S!3NAN%I@-0"/\E$Z&A&\Z22>5#5J>F$5#7=P"55JEP:23*.O5@02%3KU +MH;$B40-:J(*SKJX&H]D]W7P1*R[NJ2-4[85@&]KC.5F5ZQ<?S)KJOOG"S+V[ +M`;(,+<B6Z3W=T*;")"P[Z\=5<?5A/?575!!,K/NZV@:<''"?XYU7ZE=:&D#5 +M\A874KT-8XU)&.%-U2Z#"Z'`;Y.RX[Q3U@4P0'#7V:=UT\?CW2W4375R^XN? +M*I9<[Z+KO!'AT!@N+AGNO-?"G6:8ZLPW$%I<,_5>U=%O[:I8M=2<TM+>"L^> +M7>OCT>*R8[G:;J5"D+8LC`&%PGB&B*1/EM[GMA=C?7M,L<'>I<=XDKZJ;I/! +MQV6,.W3UX<QU6YHBDZ1Z@.%Q/4JC:E<EP((*V_$5PX.(;L1W7/53KGB=U[\, +M=3;Y_DYH(`R#E)P).<E("-@3"=WYL2/JNC`=OWRG8#$YVS"<@Q,8^$PD.Q.? +MHB':#M^ZL4V[$;;J$''OQE3VSL[X5&E0>11:(=MW1^8[L[[I4"XT6D(O7V1M +M]F5?3;O=(&%!TMKC3)!$%7.HLTV3S,$JG9.#;2?ZE,?KYU6J4OJ;?9&]I&(2 +MLF$-DG)4CPA%.YIEPR85-],`&8A:-9IF(5"\:0[_`%05+MS!1C)*R;V&TRYW +M/"T[W3IP?HL7JSI],S/"JL:ZEU:??'*Z_P`(6IHVGG/$2N;Z=:FXOZ=-K,DY +M7<NI"VL0V,Q`"O42\HJ[Z]S4\JF[`W*M65JRD!OJY)2Z;;AE+5&2K3*1W=LL +MA.`:TZ2846D$R1`4U:#`&WLA<TC\PW156X=B-XQA4*Y&5=KY&WV6;>.+JF@8 +M[H(J=,N?JB)1UZNEHILF5*QH92AIU/.V5:L[+0-=;+BJ*%*R#O75R>R+I=%M +M/J0`:%I5:0TQ&>,JG1IM'4&NGE23E=MFLS^6LJXI!SR3]%NFGKI<Q'=9EW1( +MJ$PHJ&VI@TX#54ZGTZI4&IHD%;%C1DR-E>;2:1D)2.8Z!3JVKWMJ,(DX5FY- +M4U-3*9/T70"U9,EH@)5J=-E.=()^$',5+$W+@:K?HMOHW2Z5O2UAH!4EM::Z +MWFG;MPM+'EC2<++4C&ZM0IN&6C[+`O+"FYQ$#/9=)?R\XY[JA<4/23"NDKG* +M_014&IH#F\J,="I`8:%U/32R2QYP<*6M:,95D9:5FPCSCQ1X$L.JVCV5+=@> +M1AP&0O"O'_@^[\/7SFOIS2=^5R^NZENWY6!XT\,6G6NG5*->DT^GE9LLNXZX +M9ZXKY2\*]%N.K]7HVE"G)>[/LOJO\*/!MMT/HU-OE@.W)]USGX0_AU2Z/U&I +M7>`XEV">`O7Z5$4F!K1@!:WLRRW=*8(MQ)&!R@LA4O[L!OY0>%!UFMYERVWH +MB9Q*ZCPMTSR:#7$03[J;33.\74*=KT&H2-F%?*GB(,K>*JU3TEH<>_=?4OXO +MW'\/T&KG=I"^4[C57ZR]Q.SID!<LKR[83AVO@JB`T:0876TZ9!$A8O@^W#+9 +MDB)726S`ZJT3A<;RZ3MTWA>D/)!`W[+6O6CRLJMX?IBG;C"N=0,49PN.3K&; +M3J0TF8`X51[Q4K_F^B5W5TT#IF?E5+)Q<\F?F5N1<>:T.HU&LM-!,X[JETRB +M7.UD`2E>N=4](SQNKW3[?32&%QSO+Z/AQU&A94\<+5M\-`5.PI>D2`M&DP1` +MW2+FFI9=LK;*9T=YY4-%F0K=('3S\+>+SY(:0=,%3-9(DIJC2,!/!;DG*TS0 +M5:9[B%$:4L_+[S*FUY@_HA.,]ME6;BK/IDB"-R@-`,W$>RLB29V^J187?V*) +MZJYH!P@Q*B?9D'MW"O4Z+FOS]T=0"0T*4TSFV8`,G*=EKZQ`C*O!AG`D!.&! +MIWV[IK:JM6CIID\K-NM9&,GNM.[>`#E9E<@$P2LY5O#%0JAVJ7=UE=8<T&!` +M*U+]Q;3)E8%ZXU'[K%NGJ\>&V3?6H=+A.1PBZ#1N/XEK1,3]U?9;.JNT`3*Z +M;P[TAK*0<6C'LN4F[PZ^3*8SE/TRR8*'J;G=7+2T'F;):2RH!,`*[8N$\+M' +M@SR34*1!5AK2$31$<RHJCBTD#A5R3C#25#4>>\!1FJ2%#4JQ*J)*M0!BIW%8 +M@;&4-Q7);^8?"HU[@Q'=5-E=W!!PJ%W7+@3C"&ZN"2086=<5_>1/":0US7,D +MG99EY=','Z(KRO`,&%D7EP)))6I"TKRN2#J.0LFZK9,';WV3W=R).8"S:U23 +M&J2[LJQLU]=%K<&"5D=3O@*;BYT$!2=1K:)#IQE<7XJZU3:XM:2#V73#Q^R6 +MR`\3]::QI&K(D`RN'ZC>5*]Q)D@\(NIW;KBI+I@]YRJ]2A79:MN'47-I/<6M +M?!@GM*]>.,CE:BUEKI`),]UTGAOQ=?=.:&.+BP<$E<T3OV^$+26@B,JW&9=K +M,[CT]*_\[4*U,EQ+7G=9/5O$5*HPZ'9(7&EPB1@)M4#G[K,\6,=+Y\K-)[ZZ +M-6K(R"JSW9D2DT^O.1[I2"0<PMN)Z=32US=+7!_^+A!J[3["43HB>/W0[R)F +M-@@8OQIS'.4^H[Y^Z1T_[RG&?4Z8[JH=IYS]2K-&"\`X]U`(@<_"FMY#R).> +MQ5&M1@4FC*/[I6[6^0V>W)1Z&?[*;:?:'60!8NGLLSI;?->`#("T_$.EO37$ +M%4?#M-K:0,J8_7@R:#0`(V1.`DGA$\B1G=(@:<E5%:I$E9]U!<9,#Y6C7])] +MEE]1=`(`^R#+Z@YK)),E85>KYCB2W`*TNIESG\85-E#55#`,NQA6*N>%:?EU +MG7+VP-Y(72VVN]J:W`AC=IY63;TVTZE.V$`'\RZ&T=3I,T,B$J)6L+3MLI*_ +M_*$X1B"W!4%5Q<=,X4$=,'6FN'0$B[2('T*@KNTMU$[(*U[5#&',$JI38(\Q +M\DHG'S:VMQP%<Z;:_P`36#B/0TX44_2[,Z?.=)[!7*Y@:0KKF!M.&P%4J":D +M`;>Z:@A#26`*C<TRRNUY&)6I3'&TJM?M.@G.%>CMJVH#K4$%5;IDF85SI0!L +MT-XR,B)4O;416C<>P5RBR20H[2F="L._EL01UG-I#\RCMJ3Z[];YTC:4=&W? +M</+W`Z6K0ITM+0&B`LUJ(A3:&`8^%4NVFC)!QVX6FZF0.RS.J.@:>Z:&:ZH7 +MOS./9*JS6R-_A2NHZQ,9Y1T$`'L56637I.8Z1A7^D5#<,\MYDH.HTP6$ +M90]#FC7$P!*"Q=6]2W,\*"Y<W0&-(DK0\27-.C8$C>,+"\+"K?76MTZ0>5G3 +M5='T2S;3M-3ADH[VIY5N]^TA:=*C%O`.0,!9'7V'0VF.5*U%/PS9&ZO?.>WG +M"[VWI>70T1$+&\.6C;>FUVDR5T$Q0D;PIIJ/)_\`Q`W?E=&J`.$EI'[+YPZ: +M[7U02`2797N?_B7NG-LW-:?Z<_<+PCP\[7U8-``),R.5PO-KT83AZEX<<T6[ +M<1[%=#TTS7;_`'6!TBGY=LW$1M/*W^@4]=9L'E<=K([GHS!_#C&3PFZV0R@< +M*?HC?Y#1F54\6U`RD1@#E8=(YSJ5P<F9*KVM=S*9(E5+^MKJ;DJ(UW0&,6 +MLOXQV\./M6_TX><\8.ZZ"TM"&3DK'\,4R6M>=B>5VMM1::(@-&-UY^Z^A;ZS +M2I:4X;C4>,J[2IG$H&L+2,`_"L,!C,$+>G*U-0:T>DA3M#1@'=5Z32!NI6!S +M7;Y6XYT;FP9,$(G`8(&$6B6Y.R"H9(`B$9TK5B0XZ1(0@@L@;GA2O;/Y1LH@ +M-+P)E&]"#2!WGE'0G,D_(34LMC*EIB0!QPC-@3JX$DIPP1$0C+=3_;A&&0-I +M[^R)I$ZE@&=E6N7.#?=7GDAA`5"Y>.5;-$FU"YJ:R1"J5`T?"NUV:C,*M78` +MTR1LN==\69U&'`MGCA8E>A#IW6S>&'23\++NWZG:0L5WQXB]X<LYJ:G9![+J +M*<4&<".5B^'&Z*8<<0M*XJ.J8V^5O&:CR>;R;IGD5'X,\JW9,=J!/"KVE/@[ +MA:5JS2((DJO/M-3:`U1U0`XRBJU"`H'O<79A/\0-2-.#"JUZL$PY'>5`UORL +MNYK@@@`>ZTSLKVN6YF2%G7%<:3!37=8Y=B>\K-N:I</3B-U8EIKFMJ?^;'.% +M0O+H#`A#?W6@&0%B7U\03.5J326I;^[&3(6+>79#LE#>7;B<9G8=U3J@EI&O +M'<IRR&I6+X("I7UPUE,D^G$RBNKC^'9ZX=I_5<IXFZN3,$@0<+>&-M+0^)^K +MM;2=H=$#$%>>]5NG7%1SG$F3DA2]:OJM9Y`<8[`K+)).1^J]F&,QCC>:=P`X +M$_=*<:9D'B=D!'J.)^J>9SO\+89S=($[;E)PDDZ<I.)D"`?C9"23/MOE$%IE +MIS'L$(B<A*`&P/U*9TEW,!11/'JQ,)LANVW=,79A,?S$`G'?E$(N;IR"2=BF +M;,X!]LI.P!$CY14ZCJ=5M0.<2PR#G=`)$',CME/`.VI7>J]6O^H4:-*[J@TZ +M,^6QM-K`V=\-`[*@V0Z)(![JB5KCI@R/E34!/)4+7#<3CLI:3FSN?\E4;EJ/ +M_3MWV[*2/]PH[8?R&R\C&R.!_P#(FF]?X^Q_$MQ3/3G2HN@U*?D@2$7BVSI' +MISGM,$]I5+H%G4\D'S2.<A3"SEX,ITW6@.$@X"3V@^K95F4[FF/\34?\20V* +MC?JM=],GN0TM6+U4AK9!'NM6[N*>@N!$+F^MWU+\C#K)]U-#/N#JJ%Q=Z1[I +M^A_S*YJ$'2W8JJYEQ6<*;6D:CL970](LQ3<VC'I&^%J<%6;*S;5)KN!#CM[* +M:W;5H5`720KUK3U,T-`@*T^U8RD)`^JR(FW#31P<E"X-U9._NJ]>@X.EAV0T +MZ[FXJCW!14M0MY.RSKVKYCO+;L-U)=73?RM,RH&-QI&7%`]I0=7J"DP>GDKI +M+2W;;VX8`H>B6;:%#(EQY6@X2PJ-2*M>?RCE4Z@(82095YXSN20J5T2!IDF5 +M4I4&R-7U073&FD3P5-;M'EQ&WNBK,UL)[)2#Z'#J43E6*](YDJKT0AM9S8V. +MRT;AL.]7=2K$=)K0R20$U*FZXJ<Z0A8QU:J&M.!N5K6ENVBV.%%D*G1:QI:, +M#E$UA&2I`W&221NFJD-9`)^4:5[AX:R3@']%D5CY]<O$84_5:Y)+&DGA16M, +M@#NFD/2:-(VD80WS&M];3A3R&"2Y9G6[VFR@X`B?9-)M#5J!]73/PHV`"Z9' +M)6+;7U6I<G1)"U.EMK7%X-4Z6JT6O$6A])M,NEQ6EX-L&T:37$1*QFT7W?5M +M,^AJ[?HMJ:=%K3@#99:BPZFW0%B]58']1IL70560#G]%S5]6/_%&9B"LZ;=3 +M96X%L-+MDGU"UCFN_53=-=JMAO$+*Z[<BC2>[4`(W1?CPO\`\2ET"7-Q!;S] +M%XYX5<:O56D.'I(R!$;KO_\`Q#]0=7N@`8D',_"X?P#;/-1U:K^7G=>?\UZL +M9_&/3[*NT6S079CE=7X/+7U&D@#A<1T>7,:!!^5WW@JU.L%IDKS^UJR.\Z/1 +M!I@Z<+G_`!^2!Z=EUO3:99;\97)>/P"3)V"-1P=S4_G<GV5WIU`U:D`@E8]R +MYQN`ULR2NK\,VYTZM..ZQY;\>O\`2X\[=%T2T+*;=+,<0MZU<ZG`,_!4/1*0 +M;2:'85^LU@!=(GN"N>,^O3E=W14BW?96:5-I;@XW5!CS/$!7K=W8;KHYU/2P +M(($*2!EW/""D,"<^RD<<;+;G]1ZCO&$+SF2/U1@-Q*BN,-#P-E&H=VV9RHW4 +MM<D1*!E36_1ME6'4W-9C9NY3M>D`8YN)Q[JRP>D2HHU1J"FI.]7J&.R%$/4R +M9",-T-R@!C\F`FJO])@E(Q8CK/R2/LJ-:2(W5MQ#B9.ZJ.#G/ALD]E+6\8B< +M#"S^HOAI,&0M&Y):V'`A9/4)<TQMW7.UVQC+O'G2=1Y5.V::UR/?=3=0+0T^ +MJ3PFZ+2.L%W&5,9MKRY>N+;M@&4H!5BW.NIL<*M1:Z!$96E84QB5UKYN]K=I +M1!9)*M1I;*%C6L:-_IRFJF>R@"L\:H)^ZK5ZH:./E-7J`'*S+NX&HYF58E-? +MW!+3GA9-:O+LE27-=VHQ^JSKBHW(QE73-I[ROS)$>ZRKVX#?ZL=D=]<-ILR= +MN5B=1NY80TA;D8M0]2NI=^;`637K%YTS`15R:CC+C(Y[(6T);!&(A3:(:C`U +MNJ<_*J7-0MIR,&)5RY#:5-V#LL3J-UIEI]..=U9RU&5UR](IG5L)S*\]\2]1 +M?5K.#2<]N5O>+NJ-\WRZ;I:9!65UWH%RSI+.JM:31(RX<9A>OQX^O;CEERYH +MO<Z>?J@?^:<=MT>`=L]Y0`QOW[KLAC$>_P`I?E;`S\%(EG<?=(``R0JAA^8P +M3('?(3.U'GY`2)S![1A(D!T#;E1=FDG8%)TET@QV3@#(!3-@NB2@88,B4B0T +MXR"E`)(2<`<3@(!(+0'$'.<IHSZ=65;K6[J5A0KBM3?3KET-:X$M((F1N-PJ +MP@0-D0),';]4IF.W9.UH!U3OA.UK1I=P>90)CHVWVA6*1(=C]5'+<F0`>RGH +M#U#V*HUK:J]M!HEN.Z/SJG_3]D%`@T@8E'([+6XV^TO%;0>F.'^PL_P[_P`L +M"9'RM/Q.#_PJH0=@L7PNZ*4#)4P^OG9]1T8P)$0HZK&/&6S*.EJ\J>.%#=7` +MITMP(5L3;-ZI19&D$_`*P+FA3IOTM9)]UJ7UT^L_2P$D<J&G:O=#W-CM*2&U +M3IE'37#RPN=L`5T5A9.\N7_F/94K2W)JA[!^5;-J7$!L`'=7OI!VU,4\%N%) +M=/UB&YCL4]2?Z5`"6`EVZRU$=0P!C"SK]S9CM^JNUZH#<C99[YJ522W`053; +MAK"XSJ5WH-K48_S:[3DX4G3K9UU<`D>@+H:5"F*`;IA/^+"H%I9C=$\>G8@' +ME0U*;Z1EFW924ZP>!J])45&]AQ`^0LN^<-8CNM>K_P`LDDK'O/\`F'4>58E3 +MVAU`"9]U:`#V2852S,F&F%?8V&^RM2*MF!2O(F)*T;SUO;39,K)NWZ;IND[E +M=!TBTEK:KSD]U*U!]/M6TJ7N5<#0/=$RF!Z3DI3&_P!U&P/.D&52O:H8UQ)B +M%9KOWW"Q>HW&I^C[HBO/F/UN[\J5CS(:P%T]DK:B:D3^5:-M2938`&B?=$4* +MEO4=3+G'3[+"Z_;,;2.9]I74=0(93);V7*]5_FG1).5-+M1Z;;AL0T">0MNU +MJ,M*!U"'.V4-E0#&C4,!,VF;R_:&Y:-RKIEJ^&K5AJ^:3))77V09Y>.%D='L +M138(PMRC1(9B%ETQB&](;;N)/RN=KVIJ%U4#(X6QUA[F4RW,E4@1Y!EN_*G% +M6M3IU;18YSA<IXTO/-!IL.85]U_IHN8/A<_U:LUE&I5J?F(P25G*Z;QCPO\` +M%*SK7G664=XSN)51EHVPLFTJ;@71F>2NLZY2:^^?7<`3Q(6#?AKZ[7'U0?C" +M\-RWV]V/4C0\-TJH8'O81)WG=>K?A_1+@WT[KSCHM>E6+*;-Y7K?@&U#*32> +M5F,]UV5*D!:ZH'RN%\?,+M1G`"]#T`6A/ML%PGCD-%&J=.S5:L>;63!5ZAQN +MO0.@6[6T6X_1<+T"GYG5"\#E>D>';9U>JRBW!)A<,KNOH>''UQ=/TNQ8ZT#M +M)(.9"H79T5BSCW76T>D5+?I[@VL-31D+D>I:?XHNR(V&RU9K289>UIJ>'#.Z +MNVT-<`-E0H/$B2/;*M4G<R5N0K2I.D2`$!/K/J_51T7P(G/RAJ.`F)E6LQ+5 +M)$004#WX#3E/3@Q.W;NHKCTF1PC4#Y9;5D#E7&D/9I=B51:YSR!J4P=!&K,* +M3A;-K)IC>(`3ADM47F%P``F$[7'(),)M-"B&2,PHS(:9*EIND$_NF>T8Y515 +M>9!`RBM7"F"YQ@]RGJ`#)/RH:QEQ`/PLUJ3:/K3FN#0QP)&Y"Q;L@$CLK]T0 +MT03!63U!T@Y"YY5WPFF3>>JY`X6KTNCZ!&25G6U#76!/!70V%(``Q$<PM^-Y +M?U66[I+0H00T\K1MJ$$.^\(+6E)D@?96B"T95KS0-5VD#*JUJ@9(DJ6Y>!B1 +M]5EW]S#3G*NDM1WEP?\`%,+)OJA+B2BN[B!(.^ZSZU0N<07+4C--<5)#A@E4 +M;ZLV)$3RCNZP:T@"7'8K#ZE=#45J1BU#U.X.HRX9X6-6+S4@9A25JCZM6&B? +MJK]I9`L#G?7*MUU$_P"L^VMI;J<,3N5*X"FWW&<K6\H4V0&[JC=4F@DF/HLR +M*R;TC0=9@%<)XXZ@VG_*H@ESA"ZSQ%7+R*%$R]QB%9\*_AY5OO\`U=ZPF3,% +M=/'J7;.5U-O(KSHM]7L#=&D3&1/9=YX*Z>[J7X77%G<4]3F@P7#?,KM>O=$M +M[6Q=0\H"!M"'P-2HNZ54M:;(;D1]UZM7BUXO+G[33YDN:;J-5S"`(,*)V@.Y +M!Y!V7:_B=X5NNG==N'T*+G43D$3C9<;4IO:8<WXE=7HQNYM'4:-P#CE#J/Y9 +MSV"<-.H"/NC#"''L.0II0`2V8^J9P&DNX]U(&^J=TY83Z=)D*B$`8TDD)0"I +M',>UWY7`=BA<QTP6GZJ`&-U/@<IH!.)RCTD&-N<I-V$C=$`&@XDXSA)P](WQ +M^B+)RV4@S68:/B%0#`??*>!(W&?=+DP9^J42WOW[H"C_`#^%/:'^9,[F5"(` +M!$J:V.0=O=4C8M@/)'K(1X_^0_9-;TM5%IU0C\G_`*_U3AO3[7Z\&CIM68(A +M<SX;K14=I&)73]6:76%03@A<;T9XI7;PX_U<*^/^UCYV7]74U*SA3C5E4KAK +MZQU$P.5-1.MD[\JK?URZ:;#'NM,@-2E2>0P!Q4U%M2Z<&Z2!W&$NF6)?#GB! +M[\K6IT]`A@&.%!#2HBF!3:/JK-.F*7J&8_1/38&C41G]DY(+3$**4SF/HJMS +M5;.<$J6H^*>2J%1VIW*`*I+]R@ITW5J@IM^I4E41#0,G[K4Z/9AK-1W/=%6> +MFVM.G2$1CW5MVT):0/3`3&<A12:!IRH:]`.RS!'NK5-LB=DY;`W164^JZF=- +M14;\ZQJ:/HM>[HZVD`Q*Q.IM?1)$F%8E3]-/IW@JS7N#^5@U%9O3ZA<W0V2Y +MW*V;.V#*8)R3OE6I&8^WK&NRJXXG9=3TNH/X5H)F%CW[99IB(5[H3@:0:3)4 +M:TU14$`[!"XR8!^Z1:(B("`@"0HJIU*IHHN,@%9%O3\VKJF0KG4B7U]`_52V +MM)K&B-E`5NS```"M,8`PD;I[>F`)_1*N-+)!.>$Z5E=9J0V))_LL$TV/K!V5 +ML=6]1(G/L%G/I"F`9(`[HS0W]44Z&EL:CA:OA&RTTP]PDG*PZ+?XSJ+6@$M" +M[GH=J&46B%2-/I]!H&0KS&CX06M.&A2O&)V*Q76,OJK`^N&G8*&[L@ZW.@YA +M3U&.==XV5C20R#F%F1IQK[8T[QS7C=8/C)F/*;@0NP\0T]%3S&[KCO$+@0YS +MG9A</+=1T\<Y>=^(_P"43F,96!6BJP%@D$?,K7\7GS*[H,">.5CVY<TY>(G= +M>2UZI&WX-M3_`!3!$97N/@FWBBTD+R/P%0\V[86[2O;_``G0TVS!"2G^M.Z) +M;;P5Y]^)#PSI]1Q/'"]!ZE#6%OLO+OQ?N!2L7:3GLF5:QFZYWP8QKW^:<">5 +MW?0JKZ->G4IG+3*X7P++[1KSSW7>=+#6,'JSW"XU].36.G=W'7VOL"`P,JN& +M2=ER-U4UO<00?=*K</?2T`[?=5M7K)*W<O:\N6.$PG"S1V&J/NK=(G3_`&5" +MF_\`57:#Q`<5N)8)U1S7<E$RL3APPA@.).84%5S61E0D7//(V"9[M;2!D\JJ +M*V)G*-E?'I^J;:TG80P@$?93_G;JW]EG^=#P8RK5.I(DX/LA9I;HZ#(..RGI +MTQ,QC]E6I2'`J:H[F8^%8Q1UH!WD'D*$N`&-@E4>(E15'2PD'=*2`JU),`J$ +M@G,IC(='[HZ/JQ$+%NW233,Z@3J*R;U[B[3_`(EN=1$'+868]@=<#G*PZ[U# +M]*MOZHF%LVM+`&TJ.RI`4Q$+1MZ0%.0NLFGSL[NBI-T#'^B&K4&DGMV*)[]+ +M2.ZS+^XT-,.581]1K[P0L>\KZOZI*>^N'/<<_JJGYR25IBJUP79$JO5>13)F +M25;KPUI61U&L&M):8A61+57J=Q!.5AW0=7?#3NI[ISJCHSGE6.GVLN!(@\%: +MZ9[5^GV#F&3![K4HT3I@&(4KJ6P@8]E(P!@+B`?=9:TK730UF7K!ZY<BG2=& +M8V6MU2XW.RJ]#Z2_J]WZAZ&E;D8RJO\`ASX9J=4ZBV]N&R`=BO7J-C2MK44V +ML'I'94/"EC3LJ8I,:!&\!=,ZFU]&7+T>/#5W7G\F7L\L\>6_\U\",+E/!\V_ +M4JE'(ER[_P`?4--8D`0N&L6AG7`T")*]&4X>?MI=1Z+9W=9[;FG3>U^\B5S7 +M7?PNZ#U"7TJ(I./_`,<#^R[2\?Y-9A?B0I[2K2B<'NL^NXN.5G3R"]_!>W-3 +M^7>5&CW`/]E4J?@T&"6WI/R/]%[57N*+CAID=E`74W3_`$G=3T_UT_=R>.4/ +MPFHTGDU*I<!MC_16[3P!TNA5`=3U'W`_R7J51@-,N!:%G.MP^J7D3'*>C/O: +MXRKX"Z-5;B@-7PLGK'X;6A8]U`"8P"O2J5,3D94SJ;'B"$F$/>O!^I>!ZUO. +MJ@<C<+(/AMNK14+FQW7T-=VE%TRT97/]9Z!:W#B13$QN,+4A^[8\<=X9H/;Z +M*Y!(C(5>Y\(W6DFE4#CM$_ZKONJ=/K650TZE,5*8YY"ITJ+`X.HO)_Z7*S%? +MW*\^NO#G4Z+=3[<Z8P05GU+>O2=%2FX+UP.8ZF&5&9_Q`S"AN.G=,KRVX:\] +ML$)JK^]^7DNSMM]@3LIZ.H.DC<Y(7?WOAGI+WS3>1[95&IX9I-.IKYC`3IJ> +M25D4`31:>_\`U(])[?\`\RZ*U\.,_AVS,J3_`,N4^[D=/:/K6^:W^&>R=PO/ +MVN\KK3Z9.-2]"K@&F1R5YWXCFCXA='*N/&;Q=XUT/GGRPUF\836%)KKW^8=O +MW5?I`<:#71+W;+6%J*3!4_J.ZW>W.=-"FP.,```*5S6LDG)4=D[^3)^Z:H35 +MJXV"BFJ/)_+LA,P,Q\*8LXC`[*"X=VQA18K7;H!]4A5V_EU&9.%([UO/8<RI +M+*@:U4..P,!!)TRT<YPJO:MVC3#&2`HK.D&,4SW9QV4:#!U8A.T$GX29ZMU- +M3I@-D@HIVCTB,%,=6RE:T`2>$M(,]D%2J`<1*R^MTP:;OW6R]H</A9O6:;?* +M,E!B="TMN2'#(VE=-0:2`5S5I2TUBZ>5O=-K.<P!VVRTS$E]3/E8^471Z;O* +MEIAREN&ZJ9(E+HIBH6QSLLM+]&I,,<(3W6EE,N'".K;@C6TY6?U2J:=$L,@E +M3;2G2'FW!<KU*EZA"AZ=3]&J1E7J(&%4'39I:)PHKH0P[_56(],C"KWDZ8D> +MZBL*^AMQDA4>K/#:&D8QPM#JE,MEVK*QJSG7-<,,C,>R1FM+P99E[Q4(.3RN +M[L*(`!"Q/"]IY=HR`%T=K3TP05:UBM4F@#9#6`\MW"E8"1)05VQ3<3V6'1ET +M\W!/NIW/8X`(K!@=4),;H[JUQJ'V4I&-U^D/X9SNP7FOB*N6U*K2=EZ=U8'R +M'@Q,=UY'^(#C3O*@:=UP\_3KXN].`\1UVU.H&F9WX4E&G0ITVET"?U4%_3F^ +MU5G`1QW5RQMO,+.>9]E\[*[>WIW'X=T:3M#M`B5Z[T$-;;M;,%>8?A];-8YA +MU8X"]3Z7`MQC/==<.&:;J[P6.',+Q+\=[TT:08#NX8GW7L_6'^EQ'9?.O_B+ +MOGLZA3IXC4#/U6<N>';P3>4=#X`J"ITNFX?HNYZ;4EK9`"\W_"R\+^E4A@X7 +MJ'A:C3N'?S-@)*YV;NH^A>)RF?&F<`JM4_Y@.!*T^M6].DT/ID@.X*QZKX=$ +MS/NK.*QW-Q:HN&_"M:Q&%1MX(F2IVB#Q"Z,)A5(."(]T-=X<))^@43@1L9"C +MU.U;*+(.K^3='T]PDSO[JO6<"S!0VCB'<J-?&A4IESM6!"LT9#=]\JDRN2\> +MD1W5NDX1M/96,W:Y;D@"5+4>-$!5Z3O2/V3U'?TCE;VP(.D=Y451X:=X33#9 +MSV4-2"9!6;6I#O?DG<*[TNDPTY<[?.5#T:R=>W0IC\NY*UNM6++"T#V&8QNL +MR6\KE9.'.^)G-94U,)(B%F68-2IJE%UBX=6J%L[&,*ST6V)`EIRLSFL^7+6. +MFA8LP,X^5=:0`FITFLI@`9]U%<U6M8<Y'NNCQH;ZJ&ATN'W7/]3N"3&J?JK' +M6+S=K2L@/=4?F8/NM=,6D22.$+R&MU$P0IQI:S.ZI7CX:8._=6,U5O*YSG"Q +M+]Y>XMU%7+VKDC.ZJ"GYE9;ZC-Y1V%MK()$_*V*%NUC,#Z)K*B`P#<A6Z3`# +M*Q:U(B=1&@.(D=E1OB`TAIA:-V\,81C98]^_5R""M8I:S;\O?5T-`+G;0N__ +M``VZ.ZATWS'M]3LY"YKPG84Z_5&OJD`#(!"]8Z;191Z>WRF8C?9=L)NN.=X4 +MNG6>FIJ(6@]C0PCE*SI/J58+H"O/MVLI0!PO1BXUYSX_I>H_"\_<P4^N4W'& +M5Z?^(-$&F2%YIUX>1<-K[@$+K>8X_6CXBIN?4I%DY@2M+I/36?PP<Z7%16KJ +M=YTVC6'8&5LV,"FUHCX6,>4G6E<6-$"?+'U5>[L*4$%FGW"U_*+Z\`>GVRI; +MJU_D$QF%K45PU\U]"OY>[95JVHM?0@@94G6+=SKO26R)S*&F*M!H:YDM[A7I +M$-6S-,ZL?11MI@&(RM*F!5IX<,]U6O;&HT%[:GZJ+M2KL83#CMPHGT*;S@82 +MJ6M<F=4J2A;5"(.Z49O5.D4KFBYKMB(B5R'6/#->A5UT&E_QB%Z!4IO9)()A +M05-3@<%!YY0Z=7HO]=J]I';*GI=.96U$5'!Q]LKMWTVU6!I;OP4%3I;20ZF" +M"-T''4>@-!Q&_(W4KNENI^GRI`Y74_P=1M3(EH.R3J0#3CZ(,&VLZ`H-&DCV +ME2?PE#L?NMIMO3+9+,^Q3_PU+_`?NIMMZY4,@8_5<%XWIZ.N-<=L2%UM1]RS +MTN$B,$+B_'-U5;U2DXC3ZAGMNKQ[1RF]5=Z#6<VOK`):/==+:UVW%(D[A9'A +MVG2?:MJ-.HD29Y*5:J^SK'3^4E=;^'*?XUV5''T9A6K6-/,CE9?3K@5,\E:# +MG!E.0<D*58*XJ:9R1]54>2[`F/=)S_,?OONE6BF(F2[A1H+6^8\4:>>\+6Z? +M1;28`&Y'95>EVX#0?ZB=UI-`:R.0%")`X-&Z0.=]T#3("-F7`1]4:'3W5EC2 +M6B3A!3IC$J<M``@;!"&.&X1#(_5,``?E)K0TG/T45'5',8^5G]5:?X=QV@+3 +M+#DJCUK_`-J8`GG*NASMF8N-,;E:[:?H#FXA9);HN`<"2M[ISM5$-$;*]QCZ +M.A4!I:7;@)^E@"]([IZE+3+H06A'\:W.5(TWAAO$+)ZZ6N(&)Y6M2&I@B<X" +MRNML/\8&$1\J6-%9,;H:1F%<I,&F8P2J%'S*,?X96I;%KJ0)*J`=(;$!5;LD +M[#;]%?J@!N(GY6;<NA[M]LJ*Q^MU=-,MC)PJ72:#JMZW`W_NCZF_S;O<D-.0 +MM3PK::Z^N-MH2,NGZ/;AENW2!C"U*+3&`%7L6AM.#@J[1TG!QA+'2)J5,%LB +M3"BO0/(*L4YV#OJJ]^#_``Y,94L:4>GP">,K18&N9&9*HVK"6<25(*CJ9VE9 +MI%3KMN!2<X@G$2O&_P`2@*5R\D1[KU[Q%=`6KAC(Y7C/XJ/;HJ.<[<1/W7#S +M3^+KX[_)PURQS[L:1K;/YE?LXIC><QA9%A=4F/\`+<[.\A:=*H'Z"W;W7RKQ +MR]_^/1?P\'F:)GY/T7I_3PUEO]%Y;^'E;2QDD!>@65Q-,2Z2[W7?&QBINID. +MIOD<+YN_\2E$"_%3,2/[KZ1N`'4C.<+P#_Q,VSO(+QGU#'W4R[CO^GO\F?\` +M@RZ;)D/QVE>O=#N3;N#VNC$+P[\&[HL:RGL/^R];Z;<>D!T_=<[Q:^E9MTEY +M>/N1J<Z8&W"S*KOYI,_=2L<30U`@M_55+AP\S;Z>Z3EC6EVA6!<!LKDMT>DK +M.L=P>/U5LDP%T8L2!PF2>-E'6>-/LH7EQ,;?"=C9(U<HNATX>Z,Y4[;<F%%3 +M(9L=E9HW.(.<Y"FB_P"!8QU,R1@*Q3J`C<YX3-(J20-Q$)FT7,=JX*K-6!5= +MIR83BKB3N%6#CJ+<A.YT!HV5J:35:TMRX?9`'ET"8E0U7[@_=14GN+Q'=9M: +MQCJ?#]-ULWSR#)X]E4\8=6?4I_P[1I`R24-'J1I6H!,:6[%8%W6=>7I$[NRE +MRUCJ,^O.Z:QH/N*\D3)W72=/H-I40,*/HMDVE1#W#*LUR=6(`3"</)Y<_:AK +MU&@D8D=EB=8N=#3Z@K?5KEM*F270?E<MU"Y=<5]+7$CLNCC;L%>L^I5,J2DR +M,F?D)4:$L!/Z(JKQ386SLG:!NG13X"R+UY<2-6.,JQ?7!((D;+,N:DB)W]UN +M33*O5ESR.ZM]/M3Z<2HJ#/4#"VNGL'DCNIE5D!3MRT`#,!,^6$P,JU5<`P25 +M1N3(,&.RS%JCU)Q+MU5I4#4N&R<?NKCJ+GD^G;:2M?POTCSZH?4'I77%C+B+ +M'A>TFYIM:S;V7H-"A%D,0LCI%E1H51`C*WZSPRV$8PO3C.7FO2.WI:&^D94D +M.+<]E7HUB3Z1(1U+@Z8(A=)IFN9\=40^@[&87F7B6V!H.&C9>J>*:M-UL^1Z +MEP'7J0?:O<NT<*@\)MU]&:R/RF%N6],,<'.$-`V)65X-`_AWL/!6EUJH*-H" +M)&,KEA^!._J="@XZ0TGNHG]3>^G+0(Y"P>FU?/O-&DD2MQENP4M.B0=UOCX* +M!J4KB[FJ`"=E:JVI%/+99"S[^DZC6EHD+0Z3U!C6-HUY@XRE@HU;-NN6%U,E +M0W5K=END5);\KJOX>TKT=3"V2JQL:8.G4/B5!R[NG78;K:9CA!0JOI5--PR/ +M==DZSBG`V5&\Z8'`@,!:>%(U6,/(J-P0<*&I1I%D`R#PKM?H;2=36EHY$H'] +M%!8-+W-([*HQ;FTAY+3[A%:$D:2#(4W4K*[M07AY>WW""Q>RHV8AP&0B'>!/ +MJ9'NJMU39O/Z+5#6N"SNH,TUH:@&C;!U(.C='_"#L%=M:8-NP[84GE!1T=G5 +M,%<1^)=,Z6U`V8(S]UVCW>@YA<OX_+7=/(WS_FKE/KCC>6-X.ZDZF^G3<[#@ +MMN]J-KO)X&RXOHD^:]S2!IF(^BZ"TKO-#)RN^7+G)ILV#=#-3#*M-N'.(8_' +MRJ?2ZAT@`_=7Z=%KQ),%9O"K#0P-U2-DUNPU;CS#EC3"H7KZC*C:+#(G.5I] +M&<TM#70(WRLJT;=C6M4PR)R@:6P(B%(2!@#=1HFCCA6*#6G`G"A9)<,;<*Y1 +M#?+!P$!`0V91S+?E1ZO7@!2@<@3E%.QN<F91$1S)2:2!M/LGW=//9%"]L4R2 +M8`69=-%:K$>EONK5]4'_`"FS+C&$5&AY=#(]2@YSJE,-NM0&!LM'H9#@#V5? +MKU,Z]1[[H_#]08`SE;G3-[;>F:4.,R(6=48:5Z"#`GE:E/+0X[1W5+JC)<'1 +MGNLUIKV;IHM(.1&0J/4ZI=?-;4;J]^58Z6X&V$G80LV_JM?UIK9D#=-<FVB: +M;:E(`-CY0T`ZD_3/I4U/_E@!&^F'4I&Z6$!6RS$K'ZS5\NFX`Y(CX6P7#06N +MQI7-=:>:MYY3<@&2IV54MZ1<=9,EQB5U7AV@&4FD\CA<]1+16:P8B-ETO2:G +MH:`-A"TD:](P(E6[8:HD*A2U/<,;*W2K-IMAQ`^JRZ1>D!H"K7IFB04S;NB3 +MFHU*L]KF2""#[I8NXBLY#<I[HCRSC,*2BWT*M?/+:9:3A<ZTY7Q=U`6]-Y=L +MW)7BWXA=9%U5?3#9:XXS\^R]-_$5TV]0AQ!C*\CZGT^G4OQ6>\D3@2O+^HRN +MM._@QF]U@6M"I4NVN8--/N976].M&^2(&&@'4J[:5(D#$MV"U>D.;YK&U7^D +M<!?/RG+V>VVWX<>ZCH.D@=UVW1;HN:TQD^ZY6VITQ3:X'!V70]&T!K8,X6I: +M.B8XN89[+R'_`,2EH7]"K/#3B#^Z];MJA\L'8+S[\=[7^)\-W0&?23/T*WE> +M-M^+C./#?PHN-/4&4W.V);O\+V?ICR:3#@[8"\%\"5C:^(RTNP'G'U7M_0[A +MKK>F=0R%C.:R?5EX=+;52*<']%#6J%U6&[3E5_XE@I_F`.ZCH5BZH07;]BI. +M$L;%K(:"T$_*NMAP'ZJA9$E@!*U^EVS'M+GDXX[KHY7A!;T"^I,'*.[I.8!( +MCLMRUL0(((@Y^$U_T[6PD)IGWFW-D$OP=U(Q@!X^%+>T#2K:3N$`@OSN%&JM +M6YTN!CV5BJ[T@1&%2`TM!:<'=3:G&C$B2M2L6!?I$GG<J%U<9'8(JKQY1&Q5 +M4M=J(;$0LVZ638JE4ET"2/W5GIU/S'YP/=5F4'/$Q(Y4[*O\,PR,0N>]UTLD +MG`NM5!2HEHW*;PQ;^;4;5<#,[K,O+G^.O6TF8$]UU70J'D6K3$8W6I-W3S^; +M/UQTTWD,MPP=EE]0O&4:3BXY'<JU>5M-)QD!<9XLZ@?4&N_WE=G@1=9ZJ:]< +MTVG?;*&PH_U/YRLCHS:E>^#GB1,KI&4PRD!$'NL[VMD@:C@QF/NLV\JAP(GE +M6>H513ENQ]BL>]K@N.DQ*Z2.=J"XK9/)F,%1T6>94!,Y.$J=)U1\1N5J].LF +MAHG$%+=$@;:T`#7#*T&4PVF2!PC93]$!"_5&D+';>E.]?K):!!04+<N&?OW5 +MZC:ZJDD21V6AT_IY>1`5VK-MK`U*C6-;DE=9T;IE2E:^EF8W6SX4\.M?IK5& +M9&<KIKBVH6UL1I`@+T>'"V[</)8XRRLZ_P#$@/!PM8VKS&MTA';Q4ZB8',*] +M<4F@PT\+O)S7&J]M;TVL@#=-7MV%A@*S3IP/=-7;+8(72,5Q_BZRFW>6[[0O +M/NJL>R@]CL`=UZKXAI3:N)W`.%Y_UNU\RC5])F"NL<,F;X*I,9YCBX%HG^R? +MQ=<MJM%*CM[(O#E,4K>JUW_4J%"D:_5'-W:#,;KECQ;3ZO>%K$-8'O'J//*U +MKNEI8=,XX4_3K<,H-],8E27,-89:/9:QBUS_`%!@<"1(C=/2M65[4.:WU`J> +MJR7N!R"I+-GE&!!!6F8KT65K?U-V&X**\K^8T5&.+7#A:/EM<9PJG4+1NG6W +M#AE(JWT^J]]JQQ,PBKO<<M=![*CT>L0UU([[JS6)TR#$%9BU%<W%=H@`%0'J +M88"*M+`W,I7M3\Q)W&RSKC4UA+<RJRLUNH6=:)=A5+CIMK=M\VVJ`/.T'E4B +M*51Q%003A0UZ52A%2A4<V#P5=;76DM6A>6N:E/S&C^I475!5O`'2)X6K:WUS +M4I-:7!W!;"L46VCW@7%#23RLW_"?Z&A3:*31JX1Z&_XBM"CTN@:32RLX-(QE +M%_PJG_\`,Y9Y::A_(3SRN0_$"H?*+)R=PNPJO#:)<<>RX#QK<"I7<W4-UTLV +MY1SG2G>34>3C4Y;G37%^ESI(VE<S<5=->0W'<+8Z-<#0)=[+K.6'5=-)V[;+ +M4IU&M:23@#*Q^FU6BFT@F85NM4):Q@_J.5*JU:-;5KNJ1O@`K2IVNBF'L.2% +M6L&C4UK0(`X6D'`0LJ@I5*K'^MN.ZO4:@J1ZOI*#0'M@Q]4!MW,'H)G=1II4 +M```=_E2^PPL^VN-(#*@,\K0H.8YHC,H"8R#G/U4]/#8RHFCU[X*E9@RBG,"% +M%=5@QIB22E=56L$\H+&@:K_.J_0=E*"Z=;D@UJDEQ.)5IS<;*1H`;M[).8"F +MFF%UVEZ"9Q\*ET,AMQ$E;'6J0=0=!("P^G'1=:"0KBSDZ>AMLHNH@&B9.45! +M[12;D!4^IUS4864Q)VE+`NGW#W$4VF<IKZAY5XRJ<DPI/#E$M$OB?=6/$;"& +M,J3@%9O<K4BU;N_DM/LI35TC,`%5+6LT6@?[<J"XK5:A)9L%JZC,!UZ[;0HN +M>TY/=<Z;G42\G+E)UZX?4KB@TZC.T*3I_3*KM#WR&[G"FTLVO^&>GNN'-JU& +MG/\`B73M;9V%`.J/:(WDPL2XZQ;=+Z<8(U,$+S#Q_P",>H7E1]"VJN8V<1*S +ME9.VL>>(]0ZYXWZ1TYKP:["1PTA>?^(_Q5#ZSFV@)'!7G)H]0O:DU/,>3DDR +M59L^@7-3/E.'T7.^61TF'Y=/2_$+JKJX=.Y[KUG\/NI5^J6%*K6.7"87@W_# +M:MM5;YK2!*]I_"FH&](I0=FQ^RZX9^T8RFK'H#&M;2WX6;UHL;;N).P4C[T, +M9I<%E=9KMKV[@'QC98M='EWXD=4)NGT6NVW*\PZ[U5[:[J=&-1W<<PNI_$^N +M6=6JLD[[C*\\ZG5=3K/>XX(P%X/-=W3V_I\>F\>)>YQ+B<GV6YT>Y>ZY:X +M;-./=<9TBX#JHU8@X`Q'Z+I["\8`-1DCL%X\YIZ;B[SI]R'4VDNR8$+KO#Y9 +MY()[+S7I-RX!CXQ[E=MX>NBZDT%PRDNT^.OI/:*<R8'NN3_%,BIT&NW?T\?! +M6LZ[T-TD[\2L?Q1_ZGI]1LXA==[B3M\R4G&T\759)`\R9^J]>\+70?94R"XD +M`+RKQ_1-CXKJ%HTC5(79_A[?-N+.F)F-\K.<W)7U,,IIZ`*NMH/ZJWTZ'502 +MTK';5TAH$GZK6Z&6EP)D9^5B=NG<=!8C8!I]EN=,MZ@RTYWT^RR[*`T;`KI. +MF-IFV!`AY'YETG;CG=1+3<:='\Q#@%-3NF&A+CQ$*A4=5=4T-!(G\P17-`,M +MYF5TE_#E<65U9X-T2,@E5<:HC*DN3+B>Z@=4@97.NLG"1E6&$DR=D+ZY#8#B +M/E0"K+S$QM*DHTC4=),#NEIZ_DF/<YQS[RIJ$:NQ4]C;AE4ZA)C"BZO5ITVA +MVSMOHL7=:FMZ7*-:FREZB``,E<[XAZA2UN93=SQRJW5>J"G3=+_JL7I51W4^ +MK-`)T3_=+>$O\>:ZCPA;&I7\Y^Q/^2[#S0R@&@[+-Z70IVMH-,`ANZK=0OO+ +MGU+IC-3E\WR9^]V;Q%U5M*FYH<N1NWONJ^K<'A-XHOO-N"UCIDI^BO$AKAQ, +MJ^WQCU^M/I5NVFP.(C"L7ER&M(!V"`U6,I`A974;L:B&D%;QC&5V:_NYD$C] +MUGL:^M5`&)/='2I/N*L@8[+5Z;9.:YIE,LM+,!=/L88#RM*E;Z&Z8YF5/;T( +M:V.%8<R&9"Y[VUI3\LZ829;N>\`*ZRE+HCZJW;6_J`T_*"O:V<1V72^&>F>9 +M5#W``*#IMGYE1K0,=EV71K-M"DT@?HNOCP]JSGEJ+5NQMM:@8!`63UBO4J4W +M!H^5LUJ>OTX`*I=1IT:5N[5!@+WS\1Y<O]871VN_B"\X([K0KO/F=_=1=+`- +M1Y`D&5.`'5H4Q^I4E`%S=TJ]/TE6*;(`$H*NQ$+I&*P.O,U6[P-X7#7].75F +MQ.Z]!ZW3BV<>X7$W0:+FJUP,96_CCDXJ_N'6=2HUN)G`*M>&:?F-\\@R3.57 +MZ_08Z_,@Y*Z+P?:4VVX:1*F?%3&?5AE9K:<.!P%!7J-,\8D3B5JW-*E!!8/A +M9UU;4RTC;L0K"L]P!=B-U/1I8"@J4*U)X+3J:%8M:S7$-?A#0].E\#`'9'5` +M=0@C=&\LQD05%</:QDS]$&'6?_"7VHGTDPK=6NVI1U-S.5G>)'!S-;-Y5#IU +M>Y?3+6C9+J4DW&N\-R7X:JM:M2:XR=DS:5>H`'NW3U+*B!ZQJGA38I7-:B>! +M"EL_+J"!D)7EC0\LPU4J5LZF^:57(&`@NNM?(JBHT0KU+16H9RY4@;A]`-D$ +MC*&UN*E"IZV$`*&FM1;IIALG"*/^IR"E>TC3!T%%_&4O\!472[U2MIH$`K@^ +MN4Q6O7@977]5JM;0).ZY&Y9I>^N2<[+KIRC&N+:F:+B2"6\!0=*<&W$.P.$] +MPZN*C]/Y">55:]S;C!@<*XI796-;32&95_IKWU;@N)PU<[T^M-O'*VNAU)8& +M\G<K5'3V0T4M<Y5RF[DR3[*A;N`IM;(GLK=`^H&,+-(O6YD`@25:9I)@JK:` +M:I"L`D/S!E9:AZE"F\2!!4;15H.D$Z58IR?=3:06YB44UE7:YL..5)=W#:;/ +M2<E4;MC:3"YF'*'I_F/J!]PTZ9VE/^B_9T'UJ@JU!(!Q*U&M],`0$%L6%@TG +M"E$`*::$T`X)PG<`&Y*>DV3V")PD^R"C?-+Z3MX7,OTT^H$KK+K\D@;^ZY7K +M32V]R2)/9)Q4O32M"^Y(IM..5IMM:;*>1J57H3`R@T@[K5()8>ZMF^R*%DT, +MN=(Q[*WUNCYG321N%6J?RKH%:<"O9EL[A9O,:G;`Z.36_EDX:CZ[<LM+<AN^ +MP4+'&RO*C!R56\NIU&_TD$M!W5[FV;WI'T#IK[NY_B:HD$SE:O6:].UMO+80 +M"!$A:#13M+04J;1('"S+BQ==-<YP.5G*Z61QW417OJSJ+0XR?NAZ?X(;6KBK +M7:3.5U%'I[+>K(`!F,K4L<;F5R_;WVU/XL3IWA"RI``4FS\+5H>'K9@@4FX] +MEL6WE@"",JVQK2TA:](UNO)_Q(L*5N_T-`@RM7\*+F:;:,F1PG_%>AZ-0V!6 +M3^&-P*75=&I3QW5,IN/4KJV+Z7R%R_B?S[2@_1+AMNNXM&"K;-/$;K'\16#: +MM-P(A7+A9'SKX\>^O?U'N$9WW7#=;#R2X&1PO3_Q=L76E>H^F/LO+ZC_`#[@ +MAP).T+Y^<YV]_@Z#T(-%4FH1)VSLMVP<VG<M]8+1F8C*S+"S+JL.,=L;(NHV +MM:B\/F9P#/\`9<,N:]'%^NKI]19J:UF3MA='T+J9IM`U9[+A^A4`RD'.<-16 +MYTFK-8,&0#NN?MJL:=Q2NGW#06DRK%7U6A8YVX63TZLT-`D"%:JUGD0W]%TE +M'CGXW='>ZN^YI-<2#Q]5RG@WKU?IMTUCCI#=]2]\ZWT:AU2B6U`TDC*\T\8_ +MAM7:Y]>T'N!G_):QS]?XY=/5AE,HZ'P_U^VZA38#5:'GW78]&K-#&D.'W7S[ +M1I]6Z-7TO%0:>#*ZKPQXVK47,96+H&#J)3+#[B]>%^/?.C515J-#CCY704JX +MIT8IN.<$+RGPSXE9<L:^E6S\KLNC]3J5ZC==01[%8EC6>-[=[TS3_#AY:-,2 +M5F=>O&"F]K#`*O65]19TUI;49$>J2N-Z_?\`G7E3089.%TO$>;#'VR-6NQD< +MJM5N!)@JK4J9&=U&YY7.UZIC%VE5.J,Y5NC<BDW.5DBX:R"@NNHT:5$N>0/A +M,=UG*1KWG5&`_F((&`L#K76&,8Y]2J,=RN7\5^*[>W+A1,N7+VESU'Q!?AFA +MY8XYB``EXYJ=3<=)4ZG6ZI?BA2RR8*[WP;T@6U-M5P`<<B53\%>%Z5G;TZM1 +MGJC)*W[RY%NT-;B"LXS?->'S>7VXC4JUPRE!VC9<AXCZE%TYC3[0KG5^J:+, +MP<A<7U&Y?7K/<Z<G"ZY7AY\9ROEOGUFOU3E:UFQE*FTD[+%Z54&C)DA7A7JU +M7>2P$SRIA/M,N>(LW=X#+&9/R@LNG5[BL'%KH/RM+H?1'O<*E5H]Y746=G1I +M,#6M'9:N=O$)AID=.Z2&4Q(`*T*%DUIVA7]#)`#83N89VA8_ZJLVFUH['LB% +M(N$$85AE(`3^Z.DT:M/Z*[-(K>C#@%=H4X(`&2DUK6>H[K4\.VKKBY#W#!6L +M>6<N&IX:L"&M>YJZ*BSTP1@)NG6X92#1B%.88W,+W^/'4>;*[0W!#:1("YKK +M]9SY:"M?JURUK"-6.RYVX<:UQ`[KK>(Y]KG2:1;;22K-%DGOE*VIAEL`,'E6 +M;>F/S'/LIC.$O9]):T#90U`(.5<+?;"@N&@C"Z1BLKJ4&@X?NN*ZG2!OGEHE +M=O?L_E.7(WC)OG'&ZU\<[VXCQ/1(N-78R5I^%:X#6Y/O*C\749:\Q$<JCX3K +M?S=#G;8^5<^F,>W77;0YD@JE4;(B<JZ1KI"56<R'_E)455#3EA'NA_A*;S,` +M?"LN8-4@*5C`!@A15!]CZ?SG[J"O9G,N)`[K5J>QW5.],TRFD8M]0I-IN@3A +M<_3J5*%_#?R$PNDK,+CN85'J-F`TO&%=<:B3B\I:(:]D@&3RIB*9;#L$")4? +M2ZK74])&6A2UF@L@%2<K>%*M3T&?U5.YH^OS&.WX`5[4`\M)P5!4!:#!,3A5 +M%>@\TZH!_+SG9:;6-JT0[3)'*H56,+)#H/*N=+J!A%-QP5FK%BE2:*8V1^4W +MV5RG2E@(B"B\D^RFFW/WU4O86Q)=C=<]U5YIWE.@X8G(6[6:ZG2-3<KFNL^9 +M<WFMN"W==OKA.BZNUH9Z&8A<[=.;JB(SRN@OZI=3#"[(P5SW4SHJ$F(2<5.X +MU.G5`VVWVPNB\+EKJ@!G&5Q?3JY#0"0/A=7X;J"=7<8RM_4EW'5:OYD`K0LW +MS`[+$H5"XR"M6R<0T+"M:U,;#`5EIU&3F%2MWD`<CM*N4':A&T<RHU%FG^5* +MK7%*GJ=":=+"=AW5-I==W.G.AOZJ">VINNJ_F/)T\`J^ZV8]H;`$;)6S0P`- +M$0IVD3)32J['.MSI=,*];N#X(*A<T5-QGNA#7T7ZOZ?9/^JTF"?;W3._+NH[ +M:J'"`I*A&(&ZBHGM$9(7-^**0;7#\Y/*Z9QEAU;;+#\5TOY0.P[J43=!=JH- +M![8RMJBWTSLL#PW4!I@?1=#2/IV6ZS&?U)I:9A6K*N&VH+B$_4:;749B%BU[ +MAS`:<X"D_#5_(>J5&UKP^6,DK4Z9:MM;85'1J=[*MT.V:]_G5`M-C?XBN*;/ +MRA9O";#;6[[FM);CX6@;1C*4"![*]96S*3!C,)ZS6DSCZ+$YY:CF^I6T5):W +MY52E+70X8707ENTM)61=T@QVQE6+I);@1A6QKTX*HV[A$?NK5!QVU*K'*?B9 +M:5JG3G."\X\,=0?8^(*;7XET$KV3Q6UE3IKVG.%XCU.@]G67O$@,=(*Y?UR; +M[CZ-\*UVW/3J9!F0I^I6VIAYE>7_`(=^,6V[&V]P^"T1)PO3;#J=M>V^L/!) +M"ZW'?,9QRUQ7D?XRV+74G0T3*\9O^EOI52ZFV9.Q7TCX_P"DF]+BT%P.87GS +MO";J]8@LQV7B\F.WHPR]7EUC8UZ3R\M!+OT1=0#C#=,M9[KNNL=!%E4TO!PN +M>ZS;LI"8E>;R8<;=\<[:PQ7K4Z;:5$?)[+5Z+6=3:"1]5F&[IMJEI_-V0UKT +M0-#H:,0O/=[>C3LNGWTU`7GT^Q706U1E:@W3$_JO/>FW!(:[4872=-OFTPV7 +M3([[*XUF\.@MB16R<!:-1M"M1T.:#/*Q:%85:6K5$[%.RZJ,<3J=`]]UTQ%? +MK?@^QOR2:329DX'^2XCQE^';J-N^M9L+"-H_[+U#IM\:K@TO`'*OW;+>YMM# +M@""IZ\[CKCY+B^;>D=4ONB]1\BJ'-T&#)*].\'^+;>X:T.<&NCD[JKXY\(4; +MNXJ.8S29D0%Y]U/I?5.C5O,87.8W&"KN9?Y7MP\TO;W@=8\VCZ:L@C@J(W8> +M8)V]UXOTCQG=6Q%.J\^G'JV"V:?CINQ(^04N-=98])JWD'!D;)S>4VLU%T%> +M5U_'#G$N8=("H5O%5_>$TJ3WDGM_V4F%[I<OP]$\1>);2V#O5+EPW6?$M[U% +MQHVVHR<`(^C>&.K]6JZZ[BUIS!7HO@OP1:V9:^I3U.[DG_-+G)QBXY>3&=N* +M\%^#.H=6KMK7FKR]].R]:\+^&+/IM$!M,!S1(6Q:6]I9T6A@#<+.ZCU`TZA# +M7XE9U]R>7/RW/B-2YN:5&EI]H@+G^IW,DOF8V6?U7J3R]I!CZJM<W9?:@B)* +M991SF.@7M9U1VAVTRJ/4&-8V0<E,^Z!P5<Z3T^KU&H`1(7/W_+7JAZ%9W-P^ +M*;2X'LNY\.>'W@!]2G!]UL^#N@T+>@V6#;>%U=&UIM:`UHA;QW8S;)TPK6P> +MUH;IP%:IV&Q=,?9:YI@&0(]D+FM;D\K<C#.-NU@P,^^R!]$<J[5J,!@E4KJY +M8S^H)H`6-F"8/=":C*1))`]U3NKS,"?99E[6N;EXHTVNSRDT5O6%0WMZVG3< +M2V<KO>@68H4FXX7+^!>EMMZ+:K_SD<KLZ%:E3;&J%[/#A]KS^3+XNF&[*AU. +M\#&&#E0=0Z@T,(&_=9-5[[A\`E>K>G'LUS7+R7.,A1=.+7W.H$#Y3U[-Q$$+ +M0Z59-I4]3FB8WA3OAG_4]-[7O+,$MY5R@W$X*KLI@NW*M-U#&WNNC)WC&57J +MC)GA3N?@M*KW)`&#NM1*S^H-!I.7(W-/_P!<XCOLNNO3_(/=<S4IZKUXC,K5 +MZ<[VYOQ51F@Z1NN.Z56-KU@:MB5Z#XEMYH.,+SCK`-&^U@[%:LW'/JO1+7^9 +M;->T[A.ZGZN,[*KX4N6W'2Z<'40%HPX[[+#:LYF2T-D<F4`8&RK<`"57JD!T +MSNFA#5``$1*HW;FD$&%<JO`$Y5&YR_:545"WU$CCA1WC-=$A712EH)P@<P$E +MKCC@HE8%H[RKPT\D']%<JZ9@*/K%`4ZPJM.`5(8JVPJ-@'V4ZIW%:YIP[6?W +M3!K7,]RIW,#FC5B$%.F`X@&$%"K3-*KOZ2KMJP8)X37#`XG&45C^:)&%*L;% +M!W\EN>$6L]T-`M\H8E%+?\*SIMS'7#_"T-'(W6/08]@-0Y:_*VO&8_D'&9X5 +M2WJ,=TP-J-`<!A=9=[<.G/7CFN>0W:>5E==93=1@CV6SU*DQO\P+%\05)MAB +M3*L*HVE336;JTXSA=5X<J>EW^:XUSBQ[3'W70^'ZY#)X/*WWRQU7963]39!V +M6ST]P(&#E<MTNL=/YACW71=-JCR@0%&FS1=ZA&5H42-.^5DT'ZS(!$J\*P;3 +M+CVV6=+M)=UG/<*#'23N95ZRHBE2`@@\K/Z8T%YKOW=LM:@X$"3A3_524XVD +MR5,`(B%$V-X.RE9"*DIMB"5+`<R`HP/3,J1IG$J*A+32=K9LK%O4:YH)&2DU +MH."9)45>D6NUL)]PBIR)S&/=9OB6GKM25?H5P6AKL%!U5GF6C@"I2,#PP\A^ +M@KJ;=PB97(]#>&WSV.X.RW[F[93H:0X2>RVST;KO4`QOEL,E8_3Z56]N(&W= +M2/8ZXJ:1))Y6Q94*=C:`F-<96=G8+RX;:4VVU*#4/9;'1*7E6X?4&2-UC],Z +M<ZOU$W54SR`2ND`:VAI[8PN.5VMA6W4:+ZYI!XD<2K#R'`&?C*Y#K6JPN?/I +MOPXY6ST'J3+F@PEV2%TQU8U_5I56`M@Y6;?6[2"M34'>D$&5#>-:*>8(2QIS +ME;^6X[@!1MO=!C)6C<6KJ[SL`HSTQ@&1*SLTSKBJ^Y)9_2N'\9=&+*AJTF3. +M\+T6I:-9^4`:55N;!E5A%2,K&<]N6L;IXU7IU*;I`(A;OACQ3==.J-94>2S9 +M=/USPO2JM)I0#[+C.L]&KVE8RWTM*QCG<6[C,GI?0_%%EU!@8]PF,_[A;0MK +M.K3-1L`N"\-M*M>UK:V/+7!=#TGQ?=4G>75>=/O_`-ET_CFQSCTWO'?1YHOK +M"!"\?\4U88^F<0=Y7J/5?$'_`!"R\L.ES@N&ZIT2K<5'.#=1)PO+YO'KAW\7 +MDWV\SJ>8ZLY\&3M"EL];ZKJ;@`!GY787GA_RO4YD+&N.G,I7&L-+?A>:XZCU +M3RRHQ7=;T#/S`1]-ZG4J7`;J,3D2J'4V.<[,CY0V3/*)>[Z<+EZZCK-6.^Z7 +M?@4@TG/`*UZ%1M2D)$D[A>?],OG/N@ULS\G9==0J.IV8<(EWNM2\.=XK>MPQ +MFI[2/H5:97]49C]UA=*K.JB,GYY5FI=EC\DAW8JR+[).IU`XF0-^5E=7Z1;7 +ME(L<P>K*DZK=--,&23\IK*O4J.$\>ZQE_KI*X[K7X=LN-3Z(ATJI2_#6NZD& +MAH:!S.Z];MS3%LQK@)(S*FHUJ+1,1"LEZVZ3S61X_5\"%CJ=)]-H:S^H#+OE +M=3X=\&6=HYM3R?4-B0NHJ%E2Z!#>58K564P,PI9;Q:7RVK]E:6MK:M+:8!(Y +M2-^QC/Y9,MX"R;SJ;74M,RJHNV`Q*MLG#G.>URYZH75C)52[NP\ZM655O&:S +M+"<YCLLZM3>&%KB09Q*X^_QK2Q<D5-0+S*JUKC0R`X]E4N+MU(QW"CI5C7:' +M05F_E6C86C[CU9C==YX&HLIM;+0>ZY;PM2\QH;J))7:]`L:E(X^JU).TMXT[ +M'IU2F&`#$J[YX#=\++Z?:52P1)6I9](NZ[L@@+K+\<D52]$F"H*MP\MELF5O +MT?#C6MFJ8A&_IMO281HSPNL\.>7QB^3&.2J&XJ.@`Y3#IM>J9=NNG%I2!.EH +M1,H-G\L+>/Z>WMB^;\,&UZ&TP7"?E:-CT2D'`BGMW"V+>BR>,*[;AH'$+T8_ +MI\8Y9>6U4M+(TV@-=MV4E>W>6@-*O4V:L@Q[*5C`)E=ICKIC;#=T^JXYRAJ4 +M*MN=0^RZ-K`L_J3FG`[K4P9M8E2\J.=!D`=@H.J>)[?I]-IJU`/;_82\075. +MSMG/YX7E'B^[N^HO>:;"6@K>YC/;)PSMZQ>DV?X@]+J5=)KM!^O^2Z#I_7K> +M]IAU&H#.<%?*U6G5J7]2F7O8YIG!73^#_$'4>D5!3J/+V#:5G]W&W34E?1_\ +M4',`)RHZE8/V,KB/"OBVVZBQM-]0!T97327MUT7RU=$V.]>=!@A8%)Y_CG$@ +M22KO4KE[00X$++L:[7WD#E6])]-X@;-$X^B\U\5TCYSH:!!X7J75!KHG'T7G +MWBVVRXYP5J.=['^'%V^7473@?W78R8_U7G/@ZLZWZL!,:L'*]!+R:8(^\[K' +M^-"J.`;D*E<D:L%25GD#=5JIY*NA'6+B,C?@*![1&0IBX.RW<;!!IDYWY01! +MQ@B,)XU-@%3>3Z9E`69G909O5:6J@[.%1Z82&.89QMA:O48-$\@<+&L"16>$ +MO42?5DAAV'R(2:P`AP">F`XR1A3M8W3@04%&YSB)16M,@SIW4KZ<UM)D?"FI +M4BR6G'92D6*#1Y39(E%#>X2;HC;]4O3V_59TZ.:94'4>JN8XC0P_=#U6A2I5 +M2`0.T*#I3?(NJM7,%1]7>XN:^<NS,KMJ<//]9G4*9`QD%8'5Z(#20=MPNGNO +M5;SB=Y6!=L<*CIR2=DJN:NJC)]6Q.RV/#]0TZ,D@SD_=9'6&:+B>"5?Z0X:0 +MP5/:>ZU.F:ZBP?',+H>DW$4XQ\KDK*J`X;SW*W>G58@DXC9(O;KK!P(&=QDJ +M6O4#M-!I!)W6=T^J74QZN%/T]X?=NJ$&!LI81OV+6M8!V5ZG^2(*SK)PF!`5 +MZF^!NHTM429W*EIB8[*O3<)B=U9;@"%%3,_+`W4C6X'WE14\22I9$1.%%/F, +M#/RBI@_U94-2LVGDN`4)OJ0$`?571M8KVQ)U,*@KUBRF14G'*=G46:=L+/ZK +M<NN&:*;9E/4VPK:JYO5ZK@#"T#7?7N!3&RDL.FM:34K'?DJ*Y=3;<AEL-3AV +M4EX9URW["A3I4\Y="N4[2I49KJ?EWA#X=LGZ&UJ_(E;59H%.`V`LWGIN37:C +MTUA!(C'"NENH22`%%0`8X@_='4JRW2"#*QC-W:3MG=5Z>+UODM@CNL=UG<]) +MKB"[RUV/3Z$`N</S)NI6=.YH%K@#'W4LU?:.LFYJJ/3;ME2B"")[*2X(JPT; +M$K%(JV%=S7M.DGW6CTVX:^H"3LNDLRG#.M7E?I46,IP<J&XI`;`*SJ!`A/ID +M=Y4TTRZ](&<9[JM5ID&2`MA]$OVG*J5J,&#/LH,]S/0!&#RJ?4NDT+AGJ:(* +MU:U.)$%`YL".`LW&7M97%]8\*T:C"YC1/LN.ZQT6O:53#,-)7L7EEPP)"S.K +M]+94!=IB=UROCUTW,M]O)J3:E%^DL,!;_1ZC'LBH`#O*Z#_@%.LXZFJG>>'Z +MM&KJI20F[]2R?%&_Z?0N*9.D+E^K=!8ZF][6R`<GLNW?9W%)H#ME5O*#VV[Z +M5,"'X=A8N,R[:F6GDO4^E>K2UNTJK=='<:<AI!7=WO2*QJ'33+IWPH+NV<RE +MIJ4B#W(7&>&?EV_=KA[*W=1J@D!L8GNM6ZZEHH"'Y'=:0L*=1I&`%G]5Z:#3 +M);&3O"YY>*QN>297E?Z)>NI40YQ;!&X4M[=MK/:01)]]ED68<RB*;C):,[J& +MO5J4ZX:""TXP5PO'#K&C4J^:[3J,3O*N6E44-.?JL>G5`:'2`!O/*EI5W5'[ +MRUJQMN.CI7CG$MG"G_B(GU3.ZR*%9E%AAPF%4N;\@N>"M^Q&ZRZ:VO@SW17E +M?73UMW/'9<C_`![G7,AYS[K09?.--H:<_NI<MQ=:37-4AQ<#OPJ]*N[SR2X^ +MR@N*SG"2`0/=5*M<"H2TG*YMR.@L+L.J-:YVVZ;KU;R6BHT$25SM*^%*LQY= +M$')!70731=V!<001LDE6\=L*XJ><]KFY]N5IV5`LM]>K$8PL[I]J\7D%OY<# +M*ZNTL:E2ES'*LPW>&<LI(+PV'4ZP=.^R]6\%61NV!SMB/\UR/AGPW5K!L-7I +M_@WIE>SI!KFQ`V^Z]7B\4MU7G\GDNN&_TKIE*E3:"`5JQ1H4Y;I4%K3?H#LA +M!>M<&Y)7OP\>./3S7*U6N[MU1Y:W;N%4KU''!XW*FH#+DSK6K5K:H,+>^&5< +M9,P$3`XG`6C0Z<XMET_57:'3F-W&>RD&71I.DR,*W3MW2M-EDT$G=2MMVZ<? +M9:D%!E)P;G*)C#VA:'DC3(2%$1(51FW>IE/98=[<>6"3]ET'5"&4\[E<CXAJ +M[M89DK7QBN7\47=2YK.IC8'[)>'NGVE>V=J:-495^WZ9K::CQ^9+H-D:5Y4` +M/I/"X>3^4W6<IIR'5/`M.OU5]>B(U'98G7/#%U9G#-0!WA>ULLAIU-/Z*M=] +M/;5:6/:#VE9GBUS&Y>-/":1K6=>6RQS5VW@OQFZ@YEO>.G&Y4GC7PN&36H,@ +M@SA<!U!IH52UP+7-,;K>&5Q,IM[O5JVO5;'72(DB5R5RVM9=3)$Q*X_PCXMK +M=,K>35J33(@2=EWEA=VW5XJ4RUQB=_\`?9=]RS;EK5%_Q!M1FEXAWV7.^)F- +MJ,>=,@G=;/7K(T3YC20?98EW7<:#V.`U'&1LND<LHY*UJ?P_4@X8@XRN_MZQ +MJV;'-=DCNO.NI_R[N1O*ZGP_=N=9MU'("EG*R\-USCR?LH*CAM.$#'^8-SE( +MR'&(4:`0!ZN5+3F-DWECVD^ZD9@94#U!#1F57KN]/8\*U5;Z0[,JA7=G?<]U +M8BM=D&GI)_18ML?+O7C43/9;%T<.))E8E0D7Q[)>D:=(2V=X[*3;`5>W=``" +MLTFF>9]U%-1:#5]0(A3/`!E$QL"2<]D-P0,_HHJ6F\!@&4_F#W4+3Z1ZH]D\ +M_P#6HUIS=9WH;3(`,969U!AT$QE2U;DFLZH1`.TJM<UBYLR"5VTX(:A(H_F^ +MBS;RF7DN=PKM=SM!XGA4ZHFE,PI5<MUUI;7#G3I!P0=DW2ZCVB7MD'^J5<ZQ +M2Q,3RJ5H#5I.#I`&V=EJ=,ULT*Q#P2[!'!716%4:6DE<9:5=/I+7XY*Z+IUP +M7TFB=MH*I+RZNA<%E(0Z0!PM?I`TVV3NN5H5XIM'O]UTE@_^0WX4L5NV3\9S +M]5I6[NZP[6J`X0?JM2SJ:FR)[Y4I&A2_.3E66.TA5:3I8`%-3)U1*C46J9Q( +M0WEVRA1DD!)BYS\0J%[5LV_P9(/LL7*8\UJ3?#8I5*%4:GU9!15KNPH`RYI7 +MF-!_B*D-&A_;A07=MX@N`Z7.SVA7W\?Y/V\^GH%]XAZ52!UO:`-LE8UYXZZ; +M2D4(<?:?\ES'2/P\ZO?U/.O*[P#F%UG1/PVM*+PZOZOF?\UC]Z7^N+7[6O[5 +MF#Q/?]1J1286TW<E=KX*M*9#:CQJ<X<I7G0+2TZ=_)IAL)>&:S:;M$P1A:QM +MR_LSE).G;68``;$1PIZT"F52LGZF`RI[JJ'-#1E,NEVJ5ZFFF23NI.E4C4=J +M>=ME'6HZR)..RO\`3@&P,=LK&*XS2]28(P43FM.WZI,&(!!^JD:.\?=:;C(Z +MYTYMQ2/^+VP%SEN]UG<EE21P%V]0!P(,$+"\1=+;4I&HQN1V7/\`K=Q;-\4U +MI=,<T>K=7*+VD#..,KF;-[J=4TW...Y6Q;O)8,KKVQTTP6G8P.RCJL;"@IBI +M.ZE.N((6:T@K4L3&ZJNIGX6B[20,;J)P;R/NH*@!&!A#6IMJ@#WW5I],3,?9 +M`8;N84[X7I49;,INGGNF%!M5T$81N>:C](`5R@QK&#W4OX(R.H=/%1D:<+'J +M]/'FZ=/LNV\K53P%5J6+7/U1NL7%K;F[;HM$PXLRL[Q'X=HUJ9T4Q)W@+O:- +MG@`C"CO;!I&V%+A%V\AN/"M1C"6@_*Y?K?3*M'4T3\+W>ZLV"@06CZKS/QI0 +M\JY=%,@$]EBX-3)Y6\/9=%A#AGE-6B"8,CLNDONF-J.+].%B7ED6/+73'[KQ +MY^/5>G'/;+\XNJN9I<X*Y2,-D8CA3-M&ADEH'>!NJX8]I=`7++#3I,]E5N7; +M!Q'<JA?W%1KBQI)*G;3>*IEI=K*LML*;FESV$D]UC4CK+(R+8/#C4)]+LD+6 +MIUM&F3Z>Z"[I4J,`"&G@*(.<ZEIF,)9M;EM9K7-)M$^H@E9#*IJ7!!=`'8*V +M+2I48&.;^;F5:L.F-#=9:1ODJS$]Y(:QM&U"Q]29WA=7TI](46L.\05D6-J' +M.#6%=7X:Z,0W6[)/9;PP<<\_R'IO2:=2Y#V,D'*[#H_098':-ALM7PKT9C0/ +M0<CE=OT7I3&LDMX7J\?B<,\]L;PG;-HU-#F1A=I9TF!H(`677L/+K:J8`6G8 +MM+:8D_*]6.,G#BM&H6F&C`5;J#I&1'PIG.;JPJ?4GM#9#I]ETTSM6K5*=&GY +MCR%-T[K=C&EU1I(]PN+\:]5N:5`TZ3'?(E><OZIU6E<N+*M2"=I*7+#'BIK* +M]/HAO6K,`$5&?=/_`,=LA_\`I&_=?/K.M]>B-50_=%5ZGXAB07Q]4_<\9Z9O +M?CXBL6X\YN?^I1N\46`.:K?NOGQW4NM:CYCJP^Z.C==1?E]6H([DJ_NX)<,W +MT+1\1V53`K-^ZF/6+73+7A?/G3KCJ8KRVN\`^ZWJ?5+UC`U]5T_*OOA4UE'I +M?6^L4G-TM=)'995"B;EQ>X$MW7/^'?/O*\U2=*ZI[A0H!C#^JS<O>\=+)Z]J +MM^\,864QD*'HC-%4ZOS%6J-L:KBYQGE2T:(:\F!]%G/IG2_;N](DRCTMDF<% +M0T8$P1*DDQD[+>/,%>_MJ55A8YLA>??B#X,IW=-U6U;I?/'T7HU0@C;*JW+` +MX$`*Y8S)9=/FCK?3[VQK&C589:2%K?A_XDK=*Z@UM;46$1GC_<KU#QKX8H]0 +MIN>U@U[X7E?6NBU>GW+@]A`G=<;[8UOC)[(:E#JW3&U*3VY$X*Y#Q#:/HM=$ +MS.ZS_P`.^O/L[@6E<S3(ALE=EXIM&W-AYU$#(7IPRV\^>.GDW52YU7,`@[K9 +M\*LJ7%N=#H@+.ZY1ASLPX'NM/\.G#SC3C!5RK.+7:+BD0"?96*3*[@,`+5K6 +M8.0`HV6[V]L;++2@:-P)!<$#FW#,3*U7"&B?U4%9NF85&;6J7.VP"S[JM7!] +M;/LM>Y,.R`53N2UXG2$1E?QF/5QW6=4J-=?AS7<E;%U18_\`ISW6'<6T7GI/ +MT5O236VO;N&K>)Y5VAIF)^BPPRNS.DJS:7548<W'S*RK<C21G"@N'`.V*K.O +MV@:7#]$GW%)P!F.R"VP`M">&J%CVZ!Z@G\QO<*-.$NZL^GA.`/+!=E1U634P +M/=2L:U]/2.%V<5:H095:J=0CG967`ZCC95ZS03'ZJ:5E]8I`T-``E9UFP`.: +M0/HM/JC9JM9V"IT*(:\P))25FHJC21#A\:5=L:CJ+@W8#@R%7SKCCOPK)IEU +M-N-7N$&O85IK-DF"NJL:HAN9PN#L*FF[%,SA=/T^O#1"U.5=/:UB7!H^RV;* +MI#<?J5RO3J\O,N)6]TVKKC&R6(W*-0``!6K=S7.D+-H.DB/W6@R&@`?HLUJ5 +M<:X<HJC6ED$`J"G!(_NBN*PIT_[J:VNT%X;=@@,"CL;1E:KK<T`)4*+KE^M^ +M!P%IV[(`;VV"QJ7IKI:M&-:T-T@*WH]/^JKVXSMLK;!_W6A4ZC0\RU(7+V+1 +M;]1<TCE=F]DM(7(=<I>1U`5`8DY69=9+>G4VEPQM)L<C96[`&JXE<_T>J;D1 +M&RZ;I5(LI9Y4SO.G.<I:K`&>Z&V)#O4%/5&H?Z*!PAPSE633JT:)$-RI9RJU +MLZ6@&`58:"8[(T51H&905F![()!"F+0/<CN5&1@D`945S'B#IQIN-9@(^%5Z +M==%I`<2/8KJKJF*C-+A([+E.OV+[>IYM,&%B7UO^+9MM6M5KP,R2.%;`$9Y7 +M,](O@3I(R-UMT*NH`@[KK6)5M]-I]E&ZU!R$;*DP.49]+20<]EC4K6V=>L-, +M8*I-IU:C@'#'>5HO'FU2(Y[JRVB`T#3"S_D5FV])E-V<E66,&L$%2U*()QNA +M-(@X36A("`I:36P2>55<2",8[J1E8!%70UH;`E#4:"S*A%6=M_E.'M(R<H*M +MS;![B-*Y?Q?T*G7H.<&Y/^^RZVK4`<51ZE4%1FF-UC+':[>54>A52]S(Q*Y[ +MQ7X?NJ)+@TP3_OA>P4NFN;5-7RR0[L%'U3I-.[9#J6X[+A<-NLRT\";1J4_3 +M4$_*MV?3&5R-`A>B^(_"5%E$O:T`_94/#/0CYI#FX"Q<-\6+[:YC`M_"DT-? +MUCLLWJ/3S0FF*9G9>K'IS@T4VTXGE"/#--_JJ,U'E+XI.B>2WMXG<]'N*KQ_ +M*<0I+3H=Q(:6GY*]J'A^V;Z13_15+SPZ)!8T1\+$\<VW^Y7F+NAOIM#N5/;] +M-<ZG!/U7?O\`#-6J(`PK%OX4,1IRM?MQ/>N#Z'T>+F2["[CI%G2I:-3H5YGA +M&L!+"1[PM&T\)W3J0ESI[PM8R8LY6UK]!JVK&CU`'NNCHWM!K``]H7`7W0NI +M6DF@]Q473K;KSW'4XPO1/)XYVY^N5=U>=2MV/!+Q]%/2ZM;>0#J'W7#5>C]6 +MKN#B]TCLIZ'0^JD:75'1]4_=PV>F3H[_`*]0H_\`Z1L?*CL+\WSBX&0L^S\+ +MU:@FKJ=\K>Z7T06S!N,*_N;XD/37U%>V%K<VY#J8<3W"P3X-MZU<O\IH;VC_ +M`$7;T;-K0"3)/NK#:=-K8`!4R\<R673E+3PA9,:)I-D>P_R5O_RY9-;'D-(^ +M`N@JQ*@KN<!NK/#BERKGJWAJQ+3_`"69]@LOJ'A>U+8ITQ]%U^E]3$84M*U! +M;D9*7Q8_#VKSEWA]U(D"F`HO_+UQ5J`Y#5Z3<65-PF(*SKLMH'3`,]E/V[\I +M[,KI=HVQH``>H"%;HT'U'R9,J6A2=6=J<,%:-O1#0!"WC-349O/**WHPS+8^ +MJC<P"K!G*O\`EC3@*C=RVMR,K>N&:8M+78S*1,$J:MFB#'U55\SE2<5DG.TG +MY4535F"C)$@'"9\&8*TJK5;JF2N;\3]"HW])PT#5W74%A)V0OI:FQI4N,IMX +M7UGI]QTN])@B#Z2N\\!=7;U'I9MJSO6T`>I:7CGH-.\LR]K1K&<+S[P]<U^D +M]:\IQ+6DP=USG\:MGM%OQYTS^%K/>UITN."%E>`JOE=4+"XYXE>@>)[6GU/H +M@JL&0)QRO-^AAUKXA@-YA>B_U<9V]4I`.IC!P.2HW,R5-8Q4MV$DB0AK@#(4 +MBJ58.S.P4%9TM^5;J@0>52KG!C"(I7,D20J+R-6ZO5RTX"I730(`PJB"X.#( +MGLLDLF[U`+3N7.GV673,7I(VY4O5)VO,$S_DIZ+!AT#"CI`;S$\J>FT3@J*" +MM1IO&VRK5;5IR'*XX$-R@=!,CA-$0LM:VD14PB_A:_\`\BMTP-`S">!_B4:< +M"XESH."$=$D3!D!0L)#<R/D*Q;Z@V8&Z[:<:BKR'%5JC0'YY[*U=CU856X(` +M)D2%"LZX:7W3G#@PH:K);`P?E:'E11G:52JL(>2,SA155K)'<'LK-`Z</&^P +MF%"YI#L_]U/0=K<,25>TZ)S1_$-)D&-PM.QK.:((.>5E7NJE4:YAF3$'A7K" +MIKPX3"16]87!'($KH^DUM%,$'=<10JNI51.&KH^B7(>T'5*TS766+Y=RM:W< +MV,RL#IM4$3NM:V>20I2-$U64J9<H+1C[NOJ(A@]U6K$UZXHM)CF%L6K12IM: +MP<+%_#<_*9C`Q@#>$QD&0-^Q4K#QV35#`C)*:5-:N.L$G`V5ZFXG/<K.MW28 +M5Z@9$;*BP(+8`*YSQC:N>&^4W<KI*8_EX,*I>L#ZC01)W6,HTH^&+-U"V;K! +MD[KI:+=#`J=NP`-``$*9]R&D-E8QYK&.EID'!450#5A/1JM)B4540<+I72#M +MR!LK=%V),+/8=.T^ZN4G`MXPBQ+(WWE(Q_LI-!/;'9"T0XP5&C.`TD2J74*- +M.I1+7<A6W&-S/LJEZ?4`.<%2P<?=6=:SNW56DZ25H],NPX`ZMEN7=FRM;:2! +MLN5ZA:U;*O+0=)*SC=<4RF^736U8.&_"EKU(9A8/3+T.:!^ZTC6;4<!.5NLR +MM"RICR]4F5.6>KTRH;?_`)<B!^BL4L-EWW4D:1NIR,F$!IP`K`;.=D[62X!2 +MJINIRA%"1*OE@R(`^JC-/U0.5!4%(@9PC\H1,[JP:8&#$%-H[#"FE5:E&1*J +MBW\RN`6\[+4-,QV3]/M0ZKJ*6$2T+.F*0&D;<!17'3F/`AH^RT]/&F?92AK6 +MMG$=E-1IR'7.B.?2.`0LSIO1/)=ZFC[+MNH5&Z(T_14&^HQH4])O9MF?P#`V +M7`>REHVC'0(5ZI:U'$P"FM[=]-TP5C*S>ED9]QTX%X@<\*:GT<.8"6+:L;37 +M4!<%K4K6F&Z>RSCA]:<H.D`-!TA2T.E0Z2V%TE:V;B!E)M(-`.5UF++,H],: +M6B1GW1/HMH-($>ZO5:S&LW.%F79J57P-N%9C(EY0/8VK4RR<JU2M*#698)04 +M:19$@R=U,`Z<@Y34MY7F#9:TA_0$YHTFMPW*"7!V)3OU&-)*:B<B&D-``@IG +M/(=AOV2;3/\`4EY3@XPKP:)SC&WW3EV,G]5(*9:R0/HJ=:I_,CCLLY9Z60US +M<EHP%';.-P^`FKEDP>>ZFZ-0&LOXE<YEEMK46J%#2,C*D<`T2?U15:M.F#D+ +M.O;IS_2QR[R,6FZA=ALAOZ+.%)U6KJ>,%7*-N7G4XRK+*``@<)645O1TMPV% +M*&CD*4@S`,)0"?=601D'Y_LJ74Z0@&/HKYDG!5?J(]`D[*I4=`:K<3!`4;J0 +MG"L=/&JC.T(W"#')6/\`4RXK.J4(<9"C-/@K1J"./E15&3D05L4_+$8RDQD- +MSCY5O2(E1$;@B$%2XHM<TM(!E>7_`(E]'_AKD75`$23,!>JOP")E8?B^PIWE +MBX.:"8*93<3>G,>![L7O2G4'.ES1&3[+D.J6O\)XK((_,XG]5T/@B@^TZI5I +M%IB?@)O&]H1U>C7:`?5O]5,,MXV,Y363H>GD?P=.,X&R>XVSA*P'_HVF!D!# +M=P`,K>*5!5V/"HW!,D#]%/6J0)!E4Z[B3+9515JCU<?=4[C\V3"N5R)!.%2J +MD$Y^Z(JU3Z\SLJ=O+KEQ@QRKEUAITR<*IT\S6=D_52]$7&P'1'V*D9J<[T[H +M-!C8%'0@;-GX0&[\OJ.R:F&X.K9.(G,DHBT$=CPHL.`XB92AW=&S3I$RG]/< +MJ;C3S.W=+)[JY;5!@'8\+-MWEM*-6KO"N6;IS/W7=P6KR"1IR%0O&X#!_4<J +MY6>($[*O0;YUPZI,M;@+-6'>P>3@Y5.L``2<=CW5\!KG$=N5!>4Y9EON$JL: +MH)J`D$CLI:!)<``(]U)=42*0=F?904FD.F00#L"D2Q)>M:6M#@"?CE'8.#'X +M&?V454&I4B<`<Y*>FZ'"00-B4B5IL+:A!&/E7>GW+J#X;^4\K,L7S5+85YD: +MM)C/Z*SAJNQZ+=M?3$>PRMNG<::)*XGICWTP"PB)6W:7IJU&42XQO"U6>G4= +M%8\36=C4M:VENY]UFV-1OE-`.!'[+1HN$3,+&FEEASE&X225%1@Y)4\0T&8! +M4L:!)!`"M6U0$Q]%3<,GD_*DMW:'=Y1&K2)B8A-#7OGLH#6TT9$!3V)+J>HQ +ME8S+4VK13+BJCGMJF0=BH?$UT;:UP=U1Z1<A[0=6_NIA.$C7H574G2<A:%"L +M*C1,3^BHT--294C&.9EI6W2+FKT[;?<J>BX0J=%X=$JS2QSNHTM!P`ALGW2/ +M>4+-.F!^J*0!D*:4%:&LU$!5*`-6L29@84EZ_P!):'&45C3AD]TJIF@2#V5# +MK-DVYI$`96BXP0(3.`TZ5,IM8X*X8^SN""#$JW:70\T21D2MOKG3V7#"=.RY +M.X94M;C27>F=UG&WJLY3['96E753W5JG4).-AV6!TBZ#FB7+9MWR)E;TDJVP +MR(/=3,@`S/95J!>7^IP(XQLK$<\J-G:)R#(1`<D)J8/;*D;DPI1$^F79!`4C +M:+0WW`4K&M&#NC;N,84TJK7;I:K-C3#:<[2HZK2]P&%:8T,I:8'T2K#B!RHJ +MSC'8J0R_`4EO1#R9E.A3;9NJD$@Y5@6+&Y(`^5ITJ(IT\H;EHTDA36U4J=$: +MM$*9UI2+?RH*!FI,X"LZ].Y4UNJK-I%CI`,*1E<@P>RL`->T84;J(>9[%76A +M(QP>-]E7ZA#:>#**K2=3RT_=4:M74_0\\[J\!J-)U0YF%890:!NI:+0U@&_P +MIV!H"FOR*OD-[;G=%Y`U1"LD-F>4_I@<IHVJFW`3MH-Q"LB"-N$FAF"#":$+ +M:`)V^4A;@[[#LK!+0))CZJ)U:FW=X31LWE\8"JW%BTNU$HZ]]39L9CW69?\` +M5M.&3E+A+V>^AW]M2;#IV04:[:=.&!0-K/N0"\DCWX4U*FP-RDQDZ2VWL%4U +M:SX)PCIV^@[`^ZL,\L#>041@[%:TR&FP!IGA.-_A.X`#TF4$#5NJ'?G(*$3` +M)^$SS,]PA>2UL]T!8&(S\JMU""S&2IM7V4-_`IRWZJQFGZ8TZ3&RDK$:@=H4 +M/2\-,E2UXF9P5SLX3()<")(]D#R`(*7[#*$YAP*W.E"8TX0.&9`GY4D3_4AB +M'^RHKUJ<CTR%4N:.JD0[E:#Q.1N%6O\`_EX5B5Q=>V%IU8O:/S'^Z#Q/0\SR +MGZ3W*UNI4`ZX#SIE4>OF&,`B9W4DUMF\E;PR@P#``4%TZ2<?JB#M5,`G<<*K +M=/B8(GE:G#*M4)DP<*"H9&)SPI'.!F#\@J"J=.SAW1%>OEWM[JM4#OS<=E8N +M#J]H*A<($`_=!3KM9I)DY53IP'GO),$<*Y<?D=..,*ITP.\UT']4O1%YF<1^ +MJD83$1`'NG#1,D'W'=.3+<84#.(<!!RG`[DIZ1:1/^J:L"#G"BI&_EW/V2^O +MZ*)E1FD22$7FL[E--;>/4*CJ;]1)<.%KVM21,P>RR[?3IT.SV4],NHF=Y^Z[ +M;_+RK=P]U)AP>PRKG3F>7:^K!(G*RJU7^)N:=,8:W)6L'?R2W[*::@0"PD\( +M+C\H$3/Z*5Y/E1$DJ/3.\[(TJ5VX`@[S*I!A95(G[K3J`D9:%0>#Y\:02HE5 +MVG_U;A)!`P%-J(.9]E#/_JR,R,;84]P"TSIGXE$Y%0<:;I#MSW6@Q[?S+*HE +MSJ@!&^P"M^8-@[E58W.GUG>6<K2Z('U+AU:?RX7.V58Y$D!;OABJ,@DS*UV5 +MU=A<NI.&HF%MV=TVHT9SNL&U#:@$1*O4&.9!;Q[K(Z*W,MW5RG.W985G=EK@ +MT\[Y6Q:56N`,R%*U*DJ@`2H9<TR)^JM/TO@JL]L'(E94=2Y'I870MBP_Y+3. +M!"YZDTOO6[P%T5`%M&0N67-9O;'\8--2E(_I_P!5B=&K%A,SV71==;JH'4N6 +M:UU*K.5O#BMV<.MZ96U$0>%J4CJ;PN;Z/<9`G*W;>HV`9)6S%8JLV<U'1JC` +M(3M=Z1"&I3CU`+/3HM4W9PI'/&GC"J4:P@ZC":K6!PWE4V6H5KF-X*O4QB`J +MW3Z`8TEW*M`9V69^6C%V0$;8(D'Z)B&XG=$&C<X0156M(((GA<YXEZ=K];1L +MNG.^57O*8>V"-\+-QVNW#V-1U"KI=N/==!TZZ!8)/LJ/6[!K'ZX&%5L;G2^. +MWNM2[<[-.JMZDG#L*SK$]UCV=QJY6C1>#C=-+*OL)+)E24CE5Z1ALD>TJ>B9 +M(SMP%&ED$$`;]T1_+,[**8*)YTL10T0'5YD8'=6JL0%7LBV22`K+&!SO]5EH +M]"G!E7K6F&[0@HTP8PK--H:`"Y%AW`!D2H;HPS^RF>0!G?Y5.\)TQ/NJE0V@ +M'F&45P8YP5%9_F),[JQ<4R1A94%"M!A7:3FGZY654)IU([*S0J>D=RM)%NZT +MZ3`&VZQ<&N8V6A7J$TX<#"S[9NJL7`*6+M:+](QPA_B-)DIBSDG'9`:8]\\J +M@_XKD9A+^+&5`:?J@=^`F92`=D%-HE_BS)]TOXP\%0BG\I"D,%-B2I7J$1)4 +M%057XU8*L-:`$X89SB%-BF+5Q,.<?NJUW:`$20M8#95.H0"`2%=<`+:V:*(+ +M2?NC%)VTQ[RI:0!I8.GX3GL2DG`K.;4:3#DPJ/8W.1"M$#<J-S`>$1"VYP9' +M$)V5Z9`(*9]$'X41M@#@P$1/K;O,<?*(D1CXW5*I2>T^DJ-[JH]U=C0])&-P +MJ]_4;Y<$A5Q=N!R%6NZFL:M7W59J[TUQ<V.#LK-5I$$\JMTA[?*)F5,^H"Z) +MPN<EJ7@)'I$3*0$"/JDXM/*0$N@25U:(0/E(029"<3&R=\#VQLH`>`#E4[PC +M3."%8JN),-5&[<6X,JLUD=3J,;5!,?*Q.MW-.I48UI$K9ZM0UTBXN`PN.>QP +MORTN)SS\J\:VQ]:A<!3EHX5.L_48$X/*G+O1`.0JCYUD"2K.D`[O,J"IVB.5 +M*^1&-U`_5L4$3AJV*C<V1!^BFB#(0P8@")4-J-TUVDDJOT9I-1T?NK=P?26@ +M1'NJG1!ING@_U83+HC1+0'$@9(SPA:UWY01'<<*<M'"B+PPGE`5*F!'8*.KD +MD/E2,=$$2HG3K+CO\J0(-;`]2?2S_$G#C'"6H^R-</%;%\.&J"9V6HUPTR1( +M&<&%B4*K34])(]IV6D:W\EK&B2XP(7:O*.U#]3ZS01G"T[.X!;H><^Z"@P,I +M!@R.4C0TN)&^ZSTWI>)!@`(7,(4/3K@ZB'JW4#33F55BM6U:2T`'4%GO]%:) +M(/Z+3=3BFXSNLRZ#6.)=R,+/TO2L[2ZL7N`[*\UC74X':!E5K>D#1U%NYY4U +M":9`F0>2D$%9HHUO?=*K^77,%3WC&N]>F>ZJD#3I,P$5;L7M-,ZCQN%L]`J^ +M6S5.YY7-V=3^2X@''"U.EUY8`>/=;B1WG2K@$`D_9;UE5#V@E<3T:YD!DKI+ +M&X``$E+$Z;HIAX)8`3Q+E:M0^F1G!5+I]68]2U*+@6C"SIK:W;W`C2XY/NGJ +MP&EP)4'D2-0W[H;ASVLT[GY6+56>F4O,?J$[K9HP*<3LJ'1O10]6>5/5KR=` +MY7/&;J3M!U-IKO#&G"Q.K4-!CLNGMK>*9>[<[++ZQ;R#CZJUUTQNG5?+JPZ5 +MT=A5+V@`Q]5R[V^74Y"U>E7&(E=)S&.JZBW,B)'RIW?EG*S[-X+9F58K50QD +M24TW*@OJ@;L<GCNFL&U''4Z8G9-1H&N\.=QW6A3IM:W"QW5UI.RHV!*G:X$S +MC"IFG)D'V1`/:%6EL&3@I`D_TJNVH08E2,K-,@N@*:5*,"80U!(E(/9,RC.6 +MX<IH9?4:(>PXRN5ZA3\FXD8GW7:5@'",K`Z[:C27#CE2\%Y4^FW):()6S:5@ +M1)*Y6D]S'D=BM;I]>0`=EISZ=-;U1Y6\PK5JZ3LLFRJ2)F%HT*D[%--RKP=* +M&L\!D3/U0-*&X+@WY45-8"3NM.U8/^ZSNEL<6:EJVH)B2/A9;6:;0.,A%(.$ +M&2-PD>$43^TRJMZ`*9(W5C;)A5;QTMP/F54J.Q:1)5MP!'!56RGZ*RXB5%5+ +MFE+I4+':7Z<J[6$@E4JC9=LB):S@:<3A06Y(>0"5)`TX(4-%T5HW,H+1[$2% +M%IWR84CL9P4SLA`,`@;X]T@V$1_+,(3G?ZJFS?LD`",<).$#!320`-,('#<3 +MRD02(U$)]1_[II_W*!<PJ?41D9/RKA^BI]0R.?H4B4=MFF,(G1)R906CAY6D +M.E&Z`Y(4Q)C!E-.=]TQP<[)$PJ$X1S^JC<Z793DF$$YRB$3G&2@JP3F/E$XB +M20<J(DF<JA&FPB("I]0H-T^DB2KK=P)D>RK=1ANG/U1**RHFG0])*"X:\OU! +M6*+HM1/*$9V"QC$O:G-5IR20=E+2KN&3LI7@")3M:TB0/NNF@S;@!LN3>=JF +M(2JT6N,!/2HM`01OJ!K3/[JE5.H%Q..ZM7H#1M"P.M]290IEK'"0K)MFW2KX +MEZ@RA;%K2"3[KF>G!U6H:A$F9RH^KW%:M5-1P,#Y1V5RT,R(E7.SB1B;[JV_ +M>0%`]I.VZD=7IEH@P9V4?FLF0X#W01OU<M]E&]LC;93RUSB%$\>J`0@A=CZJ +M-X`._P!U-4B%"1G,HBM<!L8,E5>D0+I\DY/=6KD0<D#'94NED,OS/)^ZF72X +M]M>L,X4)@G(W5BL0!$[Y5=\[?W1",QJ#20.?91U#J=+?DIR^&1_=1%X@D['& +MZ*E#V`;):V=D#64M(EZ6BE_C4TKP6RJ.=4`)F.ZU^D5/-O9T@Z%SMN[RP3R- +MY6OX5KZ*+]0`<YR]&GFRFG3T@-4G)]BIM&KLJ=M5)`/!PKE/5/=JPW+#OHX] +M,`^R!M6HUVEPPIJ4M.43J9>W.Y4_XI$BJP1/NL[J@T-/I$*U4:^D^!.RI]4J +M"H!3$R=PE4]L!_#"#S*CR:F&F%.&^4P-X]E6I:C7<9(XD8E/J?%QH#J<1,*G +M<MBK$1*NT7'`.GZ*.[I"-8`^B56>WT%X!C'!16-=S>25#<G0YSCL@MW%M/;= +M6,V.IZ+<D$23A=/8W&IH/*X7IMQI#9'RNBZ==MU-,_"T.WZ94=`),!;E"H"T +M&5R72KEKFC,_5=%8U`6`YCY4L)6U;/DY".YA[QA5;1QU29A6:)UU`)GY7+.< +M-;7A4;2MY<(1=+:*S]9.)5+J1)#6"<J_T2`P-DPL83:XS35T@-C@+.ZG3U`X +M6HT`MB56Z@P%NTK5CK'(]0H^H]@JMI5\NL!)W6MU.D=1QA9%>F6U)3'AG*.D +MZ;=`L!R/E60\UZX:#(Y7-VUWHI[Y6_T&IJ9YA,F5K),:VK9C6TX&X4A@;**@ +MZ1DB%)CV'PLNAJ3C)P5-3,NS*!C94C(X&%%%H8[?"B=0G,*8D:1.Z)H&TQ*: +M7:J*;QWA-JJ,<1RK;?S1PG<QA&=PIH4W5C'K"H]3+'4CW*U*M%GL5G=4HC1$ +MH5S%W2TN+FF`FMZL8E7[RV=Y9F)6/6.A\'ORF-8KHNGW'I&5L658%H]4+D[& +MKH`DX6[85P<`[JTE;U%TYD(;EY`B5#;O$?W37+QJ:)Y4^--KI##HR=^Q6G3` +M')5'I&D41C)5X`D<J-Q)_3";.F9"'5"<ND(I.(D2Y5+XB-U8)Y@*C>D:A@JI +M4]CLK#`W5E5[/##*DU2[!A9X5)5$[*K69ZIX4SW$Y`RA<)YA+5T@J,=C2J-= +MYI5I<M72"V8(*R>M4\2-PB5<H50]LSA&X[$+(LJ^1.X6BUX>T=U;$E2@F#E- +MQD)-&.4Q'ND4YC>4+R3]$VXG8)I;R@/)$(9XA,#`W3:H!$H@I/('LJO4/R8, +M'MW5C5[_`'5;J1:&AP.?96)36GY.WPI`9)4-HX&EN4^J#`<2D*)YEVZ1SNY, +M82;AI&Z!W;;H,3_FDXD&>4+B1F50G$`PA<(.^2FY]3D-0R\"9A$.YPVC/RJ- +M\[4\-/W5RI@;Y6?=NU5P-XY3XB]3;_(!S]TB0#A$`?X<0<J!KH!!68E[/5?& +MQ4;J^@`RFKNG?A5:ID:9D+H-%M]0T22)5.[ZU;T\%P^BR[NB]WY7D*A<=-UY +M=4/W3<GQ-6_4W6>O"H=%&2?99++>K<O-2N70KK+"E2=,!Q]U,6^F-*>UR_Q- +M2,'J]*FQS6!H3LLZ;J8AH4_5VS6;D8*F9I%,-VE+VDZ9=Q9-.Q`52M9N:8:Y +MRVJNDC;E0N;JR)51CNIUV<DJ!U2LTD03[K:J#!("KOIM<"8V09;[N!F1"8W3 +M8,'"MW%!E1TD"57?9-),&$Z0-6HQP`+N.ZS*3VLZFP^_=6[FSJ`#2Y8M_3K4 +MKYICG<)>J8]NJK$%N^%"20W.RH-K5O*!T\*$WE0$M+<!2:*O/=+M(43H&)@# +MW55E^#,H:]XS8X[JBTTG3N$\GN/NJU.O3+`0=T_G4^ZC3YZ-8L!#P<X"W>AN +M:VBWM/)7-5W/\QI+0X.,#NMZPK^50:<^K@B/U7HG+AG/PZ?I]1KR`=S^BU6' +M`$GZ+!Z56@@XSB5LVQ+@-UFLXK31G)4OJT@`?51")D'Z*3U&F`0LNAVL:\$N +M"RKFBX7\TY<UJUFN#:3B<X5>PHE]$U';.*E(I/K-=Z9D]U&_\Y!,8[J2[H$5 +M"]@)X@*J'Q(,[[#9)R7<7;9N"=D;Y<PP@M]1$X@<*RP?R)0C#OV`%X))4-`@ +MTSDB%H=0IP"3&!A9MJ^:1)`P4B5<MWF=1,1PM6TN-+!!E8]"HUP,">P*FM*L +M-`)6H1W71+@%C3JRNGZ;7D`2=UP'1K@!@`<NKZ;<-('JQW*U4=C0K&-P(5_I +M7J.KLN>HUVB@!,:N5T/1V_\`I@[NN&<^&]KE=@(/[(NG.#'@2F+01NHZ/HJ@ +MY2<.K?H'4T$.2O6C3)W473ZC74\%3U1(D\)6XPNJ4SJE8E^P]ETO4J3BQ8=[ +M1,%PS"R5B7#GC=Q71^':Y\@#5^JYWJ3"!($?*T.AU7LIB7+<Y8Z=E;U3H`@* +MQ3?Q*R+*L74A!_57Z#I$R5+&Y5T.,D`HV.D>RAIOYVA22`#.RC21CI.1A&3] +ME#(#2`G:??;A%2B)WD]T61B?LHVD;''PI0#&%E35`",F0LZ_C6&@Y6C4.EA) +M,?"S6M-6ZB9'=+T`KT/Y.DB5S/6;?2^=.W9=A480-IGE8O6:1F8GW4TE<W0J +M:7Z286[TNJ"X96'>TRRIQ)W*L=)N0QX!=.5J<L7AV=J[4P#9$2'7+6JIT^XI +MEDEPD[*>B[5=MC:4:CJNG@>0(_16@Z/8?*K63HH`@B5.YT`3"SIT@Y!'"37" +M(.Z`NGLG<X"(0.3E9U[.H9(SPKU4R"!B%FW%2:H$B42KML?Y??W4X@"5!0D, +M$%3[A2-!)$@`;)';;=(X$PD".<JAGF/3$K-ZN06F>RTA#L0L[K#0)D<=TB5E +MT029&ZLV]32?4HNG`Y!;';*>NW2[5)3%*T:;Q(`.Z-L]BL^UK1)<-E=H5`6^ +MGE4V+3B?T0.W_P`U(_NHW$``P44B0-DP,`2GYG2?E"3/QV*B"+LQCZ*MU*#3 +M[J5[VXB(4%[4!I20K"HK7\ASGV1"=?S[J*T=Z20$;3)F$A4T3W*8$SC]4['" +M"!PFD?EC!50GNRHW'NB>8X4;CE`_]/NHR9=(Y12W3N<(,.$Q]4`UC)A4:\&X +M:-2NDR8./94;@`W(R$O2?6I3]5'_`#59PTO+295B@[TCD?917C3(.RG255KG +M.ZK//T4UP02JM4B,GZ+:!JNE0U?R[?52$MX*BJ?EW05G_G3.YX1N#2<2FTG3 +MC[(C$ZP'><V))]U.S\C0[]$'6F36:[B<J4-'EB"E[2=(JS0.,%0_E=$?JK-1 +MH.)^JKU&@'4(A5$-4G6.Q05(R/V4E9DG&%$6DSW')05:V'C,IO3!AN2BKM^Q +M0-CR\?4HB"N1.DC[+'ZV--9KNQ6PYLS[;+*ZX/3.K961%NW>U]%IC"CN:3)P +M(!3=+<'6HD9/NBJ%PQJ6<>BH/(I%OY<_94[NU8X%TP>5>&3O!5>Z$-R95TLJ +MJRU>&@-=A/\`PU3NK--P#``#]T^O_I6--OFRL\%U,F"),9D+2MJWE46%L25D +M6]1QN00=4;85ZFXEY$@C<$8XRO5'/*.IZ74U071@\%=%T^JT;F5R/2JCF@`. +M#F]PNAZ;6AVDY@;I7GG%;K2"V8B=BI'.@1S\JO0<2R(V"L`$MC$!8KK*K=2> +M!1#`8<]7+-I9;@"1`*HN:;B_V]-,85^K+*9C'UW655(EQU?94.I4"'!S)$[K +M3:T:9,2H7L\QV<II5.QKC4&ND'NKQ+0V=7YN52J4OYA#9!.93N<^G3:UYD=E +M>V9P+J30ZF0YQ(CE8K612).-6(6W6+:EE+I$X*K.MVFF(:#"EFE[9MNXZH8V +M#/)4VKR\.,_W356.%:`2)454D3[;95EVS9IL=)NF@`.)$''NNIZ1=%S!GE<! +M85'-J`N,2<KI>F78:WTSGB5M([SIU<5+RE3F<_"[OIL-MPWO[KS+P54-QU$' +MM&?NO2*#]+!G"XY<Y).UZFZ'$<_*&I$DSLH&U1JW4Q=J:3W2QVE6^E5G!Y#X +M@+8IN!:N>MW0_!P%J6U:&Y,(W!7K)D1A9%]2(:0MUYUTYD!9G4&3(V^%FM.8 +MZC3_`)>)^JALJA#8$"%I=3H^@[8652@2!NK&*W^F7&T\\%;%G5U-B8"Y2WJN +MIQN?<K8Z9<2(U#/NJDX;['[05,P@O$N,K/IOQCE6J+YRI8Z1;VA.P'^K*C![ +MYA3!T#&5+%@Y(_+*-I.2H@1DDR4GU-(.>%-+LUV^!'*"S9$N)RH*8\^MC(5Y +MF`!P%+VLZ"Z<D<+/OJ)()B3[K1=(!Q\*L]FMI/"5'*]6H@2<>ZRV-#:@>.%T +MW6;?4TB..%SMRPM?&PY4C-;_`$DEU$96G8!PO!/"Y[H%<L<&D@Y6[0K`74RM +M:25V5J0&C/ZJ9SAI$K)MKN&`<*2I>0T;J.D:0?'^92U0-RL]MWJ$DS\)VW8` +M[&47:]4?Z2>2%EUG?SQ.<J5]T`WU$?(6;4NVFY'J/Q*7I/K?H.EC<1W"E8X$ +M0-EG6UTT4]U-_%-VF%--;6R1`$?=)A$;[<*I_$9P04[:XTZIB.%=&UI[L@RJ +M'5WRTP),*=UPSO)^50ZC4#FELB$D2U7LWB8Y*FJ-!!)&5#T\DY@*9S3D!T<J +M155P(,S,%6[.K``,8455ON3[J%C]#@"K$:I,B1N@.(YRHJ521DJ02=R%*'J. +MQ(,A1N,B>41`!.<>Z!T"2,2@!Y'!*@O'>C'&V5,\S_HH+LS2.\K42H+)X(R= +MU8:9)AQSQPJ=G!,?NK3(F`T!2%2?TX3SP<2HW.(P-D[7%Q"H*3![*.I,P70B +M).GM"#5ZT"QHW2,`1.R=WY=Q@(()!,R50!B2`250N#INACGNK9_,8(RJ-VXF +MZ"EZ3ZTZ>6M]MD;B'TR"H6$!@/9%4=Z-RFMI5*X&DQ./=5JK3J@*W7`)SQNJ +MS\XP4B17((.(0UL#<%2EHE1U&@B()(5$%)L@DC)3$>HC92AIG/V2+1N$1B]; +M!!F$5*'4`8"DZXTFB2,$#=5.F/#K>!CV5O;,$]PU>W)4=1@=&DX2=.J"(^$X +M<-,;=E16KC)!W"AJ/AT$*6X/K.256J&0<Y50-8`D\*%H(YW4DRW<X4=9TNW@ +MC]5!#7(GB2L_K-+5;DM(VW5]SM39=NJUZ"ZV(/8K4[9O2ET5Y-H<G!4U:3_F +MJG0W0]["=NY5JMB=2QCQPN78=+-BH+@SS@IV$Z\R@NL'2)GNK2!&D!/+5$TC +M2,IY'=&]OF*PN'&H(VQ!E:UM5)=!B3@`KF[)W\SU8C8+8HU&G3!D`X*ZXW:9 +MQO\`37D/'OL/==)TZJ&!LC)W7*].<'56`20WE=!2>W0'$B=ENO-DZFTJ-=3W +M`]E9?5TT"XC99O3Z@-,,]E)6>^K=T[<'$R5BS2XU>Z73_D:_5+E9KSH`.=\I +M42&-T[`;IJH:XQE9TZ2A8!`!(PHJI]4@XYA2M`CDJ!Q]L<IH05/34QWR"BO@ +MVI0@-SNG?3#G2/U4=8PTMDQ""@ZMH:V@Z9)RKH>S6T2J-)@KWT$0&^ZFNFFE +M6D"8@)WVR*]IM\T;*G=LTLD.$*[2+'TSJ'JW454!U,YSP5-::WMF$`D:'1W* +MT^GW/I`:<=E1=1)!(`QRH:%7RFNP1GG8K4K%>G_A:\N]7_5]MUZ'YS=($PO+ +M?PGN`ZDYWO/[KNZEP=8.K[K&N7/&\MNA5EX$A7J#@6[_`%7/V-?.#]5KV521 +M\K5CO*N#TO!!*TK3348%F_F9A6.G57!\3CW6-?&]KSWN83,PH*SFU,X'=7G- +M#V9"I7=+2/3LLUME=69%-T9`"Q6LF1L#WX6QU1Y%-P&)"SZ--II&3]D1")D@ +M&85JPK>7'=0-I%K^W*3AI=^:0KM'16MQJ8,G=7Z%3T8."N8L:Y;`U+9MJXC! +MW5TLK8I/)&\_*F:Z,`X6?0J3_4K-*H8_-NHU*M:]B0J]W6]6D<IZM6&2J=`^ +M;6F<=E+=*T;*GIIB-^RL,&J)_=04G`"(RIFGTRI(HG-Q"C+8$QNCU"-TU0X` +M[;(*%]2;I(.,+G.I6VDN&.ZZ>Y!..5D=3I&/RY42L2U(I58SA;W07BO<YSE8 +M56F6O[+:\&MFM(Y.ZK.G94:#-&R8T6]P5)1EH&?HD3G*CH`4&`P$G6LGF=U* +M#&V2B=4,Q":%6M;PTP1`6;Y`_BP,F5LW+H9DY6?2<UUP$LX/JTRW@0W"-EL0 +M/4284K'8V1M,M@<*:Y57-)W'*847F<JV8W'=.".0J,^I1J#+3$*CU`O:"'2M +MUQ]N%D]9@`DI$JK852&",JU_$M<<E5;-@T?*G--KR3D$I-B5M1N<X05=.X,R +MHGL<T8G"!^L8""S2?I<`7`JVUP,$+*%2,D*S:UQB"G8OG2=RHJF"8,@H@X$" +M#&-BHGX.#A`G$D08^JK7?Y#LIPX1NH:PP03NJ52LGCS")&.95L$`$%4*9T79 +M$B.ZMN</E(B0$3(.W=$"<F84(<)PI`09<1A4$T]T!,&?V1C#2-X4-4[CA0$7 +M%PPEO.$&J(A.W:`51'5Q*S;@D7329Q[+0J&'8_19UX?YX,0EZ1I4ZD,!A#<5 +M`QFZ&D\>4!^JBNAKIQRD2HVU=>=_JF/'<(;1GELR[/[J0C,I.C2*K@J,>H'( +M"DJ\XCV40D"`(E4"X0XC.?JFJMC:8'=%$$H71O\`NB,_J@_E.!Y"Q^FU-+W- +M@A;G4&!U,SD$+G+8Z.H$#<[JWIF=K]1LF<D]]U&\;QA3U`-*KN=N-R@@K@@C +M]E5?CZJW7,;'(5-T$Y)PJ@7G8C`*"KR!(CNCJNTM`DPH7DO$DR0H(*IGC/=` +M^#3/J@_*58;EI48.X=&1N%48E(MI=6+7.Y&/HM&JX3!V*S>I?R^JM>"`!RKE +M9XJ-#@GVK>9"<8.3,(:KMYW"![W:#&Z!SG%GJ;!0@J8]`X3Q[H&5'!H&H?9/ +MYKO\0^RSPV^3`XT[@M(TP>2M*RJ!SA)&>52\04G6_57B``?=*TJG!C=:\>6X +MZ>3%U73GAQ$'!,;K>L7:G""<87*=%KM:R9]<X706=RXU?-<07'?W7H[>/.<N +MJZ97#1)XY6ET?34J/N"!DP(7,6%V_4*;1+G&,+JK!OE6[&`#(6,HQCVOM,D. +MF$1F8*C;M,_1$VH($@D^RRZGJ8;@084+6@B2#[*2HYNF-C[J-KB[`B`H'8T! +MWPHZU/T&<%2T"T3(_1-7V)SLFC;$M2?^(OC$=E=<[U$.$CNH+>F75GU=,294 +MCVN!![I.D#4ID-<YFT*NRH1NZ1[X6@W%#D^RJW5`-9J`(^BBJ]5H<):)![*I +M>TM%)SHB1"TK<@M@`PFZC3#K5Y9G'"6Z339_"2MIH.&6GG]5VG\9J>?5/NN` +M_#:6TCP5T3KDMNBV2IC=UQDYKJ>G7/JP2NCZ?5!I#,%<%TR['FAL[KK.DW&H +M`+I8Z8UTMLZ`#RI@[34!&%1M:LQE7(!9@K%=8V;)X?2&4=5@.ZS>FU8=!,1P +M5HNJ!M,PX+-;E87B"C+]`&5GFDZDP!TB.RV:X%>[WD!1WULTL,#(V)6-ZJZ8 +MU,MU[D^Y0W+9.,#N%+6I.IU%'4>-B<JHKTWEKA'ZK1LZX']1*RW`%^(^5/1> +M0))B.RJ.AMJH+!ZE>H50(Y7.V=?.ZTZ%Q#-6T(LJ]>5Q.D&"5/T]NFG/<K)M +MZHK7.^!RM>DX!D8@<RLWMJ+32`8V4S2(!!WX55CP#ONIJ3\YR/=54[7@C)RF +MJ$`'8!#,F>>R3AJ.5`#H<W&96??4YY6D_`@!4[EH<TD[I1@WM(!T*[X/?IKG +MY0W;!!D!'X7HD5R1W4G:.N95$9V(3FJ"0(5=H=M*(`$JM18UB,%(U"23(5=L +MZ=TVH\<()+I\M(F`%0MW.-S@QE2W+SIG95+*3=:IE+T3MNL=#1'*?S.)5=A@ +M!$)F2@L:\&$XJ'`4'P$XE*HR\3@DA9G6'2KQ$YF%F=7B8!1*:P<?+A3:HB8P +MJMD3HC]U*7>HSL/=2+5B01\I.`)[J)K]N$X=ZXVE4#4I`@Z5&T%IV*L.<2-T +M'YO=30=M=^,?*=U8Z<@X2`;&=RC+&'$A!`;G,1]E&^X&))RI32;MA15*(&QE +M7E%&YJQ<"(A6VO#VZEG=29IJ!P,0C8][:8$E/J-!CNY4S"2/[=UF,N8)#E:H +MUPX`2J+<^D]U#5._!"<5!W4=4C:440=.Z?4)WV46J!$I!W(1!/P(&RS+V/-! +M.RT:A=!!/T6=U&=8DCX3XE7J('E`C8>Z"H01&?NAMG?R(0ETG*3I:>(9)2ID +M%N9"$N@1O\IFD:>RJ(ZL%Q`.$+\#L$3_`,RB>X]P40HR$U68PG),25$Z9,_< +M((+PM\LCV7,51IZD-]UTET'%IPN:ZK++L.`"U>F?K5>6Z!C?NJ=4EM0S'PIJ +M;II!P,JM>._F$@_5(@*I,F1NJQ$O#I/NCJ.)`,('.,1C*(:H6G$?JJ\Z26G8 +MJ6KC(,_"KU<9B?JFBH*NVD?=0L=O.$=PXD_YJN7DNW,!5&5UP@W#3SW5FG/E +M`\_NJ?6S-P#LK5)W\EI:F7]B='.7GE)SF^7`@>RCJ.=(+HREK+A)<-ONI5A` +MXPV0GD_X/T4)J'M/NF\P_P"%&]/G7\3K1U#J!JMD-/8KG+*J69:8E>A_B=:" +MI0D4B33;F=I7FK*FG^61)#MYX7+"ZNG:?RQE;G3*HD#_`&%T?3JQ+6F3(W7) +M=+K%WHG![E;_`$JX`IZ&G;D+UX7<T\_DCH>CU75>J-$X;P%VG3G.=I+CMC=< +M'X8=_P"L<^",KL^F58TD#;NK7GO%;1(:R2!E%2;B8^O"AI.+QJ+I4K"XG$Y7 +M-T!4R3RFEL<[(JC2#O\`W4%0%KMP<HM6;4&#,`>R#J)T6QAVZ>D\Z(U3*@O' +M:[BFP3[I4/2`;;-$"2)4-;43'?@*^YLB(&.RK5&Q6$;J=*B$M#02E=-'EF#& +M%-4_F;B"%7N\-W)0X-94&NIG.4UV"V@\$3(X*DZ406D@G>([*W<40^V?,S&R +MF71`^!7<D`;A7.O56T[X`'/RH/"-'RG2YI'9+Q93+*WF2N6-U8Y2?RJSTZZA +M[7$C_-=?T"]&D9_5>:V]R0X=@NC\/7\.:"9GZ+TSE7IW3J^K25L4'@LCNN3Z +M%<A])OJ"Z"SJC2#*QDWC6BTEKA&5.ZX.C1R52:^6$S$)K5X?=^HX!6-ND:ME +M3:*>HSGNGN&G5Q$*6E&@:3'U2J@&9(E8UIT95U1#G$EJS+RA!."MVJP'_54+ +MQD-/)[*#`?-.MA&UVK\RN5K=KP21!Y5&LQS3`.`DK.DU-^G'NK#[K13^5G:_ +M?9-=51Y>J<^RW*E;O0JFHR5N,J;`F?A<GT"Y&@`GZRMVSKAS?[J:7;6ID!H, +M$*Q3+0!*SJ3Q$R?E6:-2>?HHUM<8[U8^%)J(,JNUX.?V4DPV>Z*)[OJH*Y!, +M']$;G=B@<&D&5!GWP]!PI?"P)J?7DJ'J`ACC)]D?AA^DR2D1T8P,Y'=$"-U& +MRH"S@2A+@2(<C25[@,0@),GU0A<<ZB90%T$R=_=`-T_^61./=5.GNFYW$*2] +M=_+F?N55Z:[^>2,Y5J3MNM.-T8=`_P!55UX&8]DFOG))459+S.\A)K^2?HH" +M9P$.HPBK?F-R!CNLKJCLF"85DU#!S/LLSJ50_E,2JB2V>`TD291.?F05!;._ +MD[_5$TB?41)YV4@LM>0-YY1!\G=5R[:<)P[.=D$X?G=&Q\#C*KL>"-]D[70X +M9^J;%EQ.-DB\]U"7\&8*<.X!_54$YY&9E`7DNVW35'@;G*&0[Z>ZNT5.HG.4 +MJ8'D[8_9-U+4!N82M_\`D`[J7L+RVDX*3:3ID(FN]4(VNAW"I`/UM[X4=2X< +MP9G/Z*V#+5%5I-.[=]U!"VY$_P":E;<-)`U0H*M$<*$TG;#A!H>:TM]+I5/J +M)`$G"B:VJUQSA0=2-9M/97:5I6;@:`)=$(7D`K/Z;<5?X>'`X[(GW1+O4DUH +MJ\'`P#PA<3&VRJLNFZO[(S781C'=42U'2V3NHAOLA\YFG\WU0"H)W.564Q/I +MRHJFQC"=U1L;J-[@6SJPFC:O=.,?(6!UO)+APMN]<TM*Q^K4]5J\YF%J,4/3 +MWZK82?LFN8`R0JW17_RBPG93W#?5CA9QZ6J[I`)[*%SR02IZ^&D[#LJCC)C[ +MK2#+@84%PYLD#[J7&DE4[N0=0VY0VCJ/F<3\JJ]Y#_S`2I7N)$@J"L?0851G +M==)!#I,*2S?JM!_4>ZK=7ES/92=/(;:-!S\E3+N+.DI+6M)(CA"8%,$'"5:" +MTXSPAI@^5I!!]U%@FM!;)A/H'M]T+#Z1A%/LHV\H\54&UZ%9KID-/RO)NK4' +M4.I50T`M!R9VRO;.I4P]CG')CO@+R?Q[9NI]0>Z<3,1[KGGQE*O@O<9EKEH+ +M0=.X^%K=-K@4M((_NL*SJ/IO:`>^3PM2E6UR74Q(WC"[X7ZN4VZGPW6+*+<Y +M)[KLNF5I#(F8_J*\]Z3<:'TFC`,;KL^A5?,8S(GWX7;6X\?DFJZJU?-,"02K +M=-SM,`"/=9=C5@ADM='97J+IP=6T^RYV+C4U0GYA5ZF7C?\`S1N>[41OV3&2 +M3P2HT3JFEA."!N`HNG@5*KJAG?"#J-0TK8GDX1],+V6K=49[IVB_JVF=E%4$ +MG494EN\$?/":K),D;84L:B*W'J)WE07;7:S&/W5JF"!,;SRJU1NMSL\[H([3 +M4PYG)VA7GUO_`$;@,8YG"JZ((+)!XRGZA4<VQ?\`:5/B-3PPWT!\R2=T_C$. +MQ!/J$84_A%O_`/3Z;].$WB!HJ5MH"XR<L8=N-+G,K$;*]TF]\NJV<0=Y4O5+ +M3^67,&0=UDO+J+@3E=\,ERCU#POU!II,SE=ATZNU[&Y7D/A;J1#V`E>A]!O= +M=-I!6\HDKJC6#:;CJW]U'9U7&[!`QW6>^Y\RJVDV<K6LJ>B@)B>5RRNN(ZX_ +MEMVM<&G'>%8W&3/NLBUJZ7`$C_):-!VHCU+-CI*-S1I,`RJ=VQI?[_"O'/[* +M"HT203)E8L:9=>FT$B"J=>CC;'*U+ML$@`RJU>GB2D1D7%N#)!R?T5&^8YM* +M"86U780TJA?M#J#I'"L2JG3*^FGI!S^ZV>G78TCDA8%M3(!(5BA6-+>!E:E9 +MKK+6X!;DQ[*];U/2,Q*YCI]WL)_5:MI<:B#@_5+&I6W3J>H0<?*G;4`],E9M +MM5'W4X?MWA9K6UPNU")W2<!I&?HH`_;(E23C915+JIBBXCA%X<8#!2ZEFFX1 +MB,INA/%,B-I4G:5MP(&3[HVPJXJ-/RB#C,3*TJ8]^/E!4,'>2A)!Q@%#4)V. +M%-"O>F1OLJ_3?^;GNBOG>@J'I9]9DR9PK?B1L:A&_P`)M>(*B:XS&(A,>ZBI +MVU1.Z(O:3,CO"JD'![^Z3@[28)E-B<OW,8Y63U:L-?I/*MR[;?V65U)SM>!R +MK\%RS>?+!"F+O>51M"?*!,A2TZDNW*S%6'.)_IPEN,&"HW.!.1A#J'?'""P- +M38!VB<J2F1_LJOYFWV3M.,F/JD-K#G.(QPD''<E1%_I@<)PZ!))5B)9D&4PD +M'>9]U%YF-T@Z>51%U%WH*&S(\D9^B;J+OY1SCY4=B[^5OE*BP9!D)&0Z5&YW +M\R9^B?428)Y06&ET`IY)89CWRHV.QI"9S^$#5=\)##8[H7G.#$IJ;G28*"5D +M$[1]5%?-#J9D3[2B:XYXY0ULTR"58*E@QLN`:BK46.>3&>RCM'1=.!.)4]0R +M3"D*K/H>J02F=0<6G=3EQ`"?4-)Y*ND4'4G`8)4(-459E7RX:C.Q*!S0'3CZ +MHBD]]4&0#!*%U:H&Q!5\M#C^7Y05J8#<-'U5FRZ8M]<U!@@A4KJX+Z#A)V6Q +M=TV$F0,]@J-S;,-)PTC/NM[K%8'3KK1=/;)WV)5\W;2(.ZSS;:>J1."5:K63 +MB-33"F]6GP5Q7'ED[PJ8JM+Y!W2K6]700"9A9U5M:F2-/RJC4+\&#]%!<P6D +M@*@VXK,;$%*I?#\IY5@-[@UWJ^%#7<TCG&RB=<MU;IA<,=Z79^$T*76@TT-1 +M'R5'TFI_Z8MG"GZH6NMW1)"K=$$-<X1"F7PGU:.XSNG)]#C(PGU-=(+=D#IX +M&#PI5AFL)$A/Y9]TFS&/W3Y_V5G<=7!7+8HF1@B=]EY_^(MJUU.H]HR.>Y7H +M5=S2")XW7,^*K8U*%0;R)SPKY)N.'COKE'E#7Z*A:!B<%:%FX/8T["9A4^JT +MO(O:E,-(@]]U-TYWY6C`:5,+N/7G&S1=H\J3G<05U7ARZ#FX<&D#OGA<E0@, +M9]EK]*<:=1LM(;NO3A?CS>3'<>@]-JM--H[[S\+3M*Y+1,&-ES72;IKVL`)' +MN5MT*LZ<[*6:>>72^QS#4DD[X4FN2!G[JJTOB8GLI2X8<=Q@SA8TZ2JW5'M? +M=MI-<7'!(4U`C0&;`=E7HM-;J#JN(;C]58JC0>T_HH)Z=8!P`/U[JVW2ZGD; +M+,HN+KAH)P5ITX-(-[CE6K#`'1@G_)02!4(GE6)`:0)PJE4^H_=1=I6YR3[R +MHNJ`&R?C=34W32$MVPJ?6ZFBV&PEP^J6);PZ3PSZ.D4LQ#0._P!$_6&R0^9` +MX1=!+?\`@E$[2T)^I#52U8@'"XSMQPO+.K-8^CI`XA<_URSECM.^\+HJ;'`C +MW5>_HM-%T@+=_+O'+=(N'6U=K3JP<P5WWAOJ8\IIU;#NO/\`K5%UO<:Q@:E< +MZ/U(TF-!='$CNNV%]HYY<5['X;J.KU14)!$KIJ-3,`_JN#\"WH-FPATF%UMK +M5!`,Y.5BQO&_&I)#ICZA7;&K.'$`K+IO);$J:D_R^=NRPZ;;FK`G>$P@YG*J +M6U<.&2(4X>"!$9]UG3<H*S=\!5JS);&`5<J9!RH7,$&=PLJSJ[0`=4+-ZCB@ +M[$>ZV;FFPZ@=BLKJ[!Y+@WZ*Q*SK.F8U`XF)1U*32XQ"EZ?2/D`]T=>G#HXX +M1&<7NI'\V!Q"N6=X6ELF9S!45:D2Z`,E5JE/2[&",K4J5U%E=A])L'?]%HV] +M66@3NN+M+MU&J`[8+>Z;?->&RX!+$E=`Q_$J859:/?A9M*J'`:73/96:3IS. +MRPZ'OS-%P!E'TADT_A17#AY)4W29%(P0I!?;@'V1-=GE1S]$3=.)("JI(,S^ +MZ%QW#M]DY+8WW4;S`B1\H*G47``CE1],`UDCOPBZ@X!AR%%TQ_/<\*4:E-V) +MTHO4<[*)CL"%(TXGNFC9.<`(Q/=$'PTB5&Z9G&$%28[JB34P-=.>ZR>JN:*G +M;*OU'::1XX63U1\U0`('LH59MG#R0)&`DYWJWP5#1GRP,YY3N,.P3ME)2IQ4 +M'!^B37^M0%VT)B\@S@#A!:+AW3L><*&0<1N$F'2X23'RE%L.YF>Z;4`2?[JN +M7^DQ*(/P)@H)=?`!^4=-X+<[RH`Y)K@,JANHP*9SB%'8QY>#LFZ@_P#DD$'Y +M4=@[^6=]E:D67:B<NWPDTG5_=1ZCPGU'G=!8:Z`F+LG"A:21O"1=F.$$CC.[ +MH3<^ZCJ.Q]$U-V!`03TW2<(JQ;H,Y(P%`UWJE&[;O[*Q%`NB]B8DJVXR/251 +MNSINFD#G[JW3/\H.D!3Z?#N,L@1"83VR$!C48*1/JW6@-3#MDP,;Y0UIR2F9 +M')W[HB1Q`9@E0UZA((RC<<?N57>9G,951#6$_P!U4<!K<2..%:J`Y!.%#5RZ +M08[JHP.JM\J^%08RKU-VN@UT3(W4/B.G_*\S<A-85&NLFP<A6][2='N)`('* +MS;EDF3WV6E7/HQ]U0NYTG)A5*J&DPDM(F2H:UI3,X&5*\Z3@F9Y3N(?3+MHP +MIH95U8AQ);QV51]K5:202#)@K8>88=,QRJ]1WJQVV5T;8M\VNRA4D$X5'I=W +M4;4<#N"8"Z&[:W09SC*Q:%)C>H/$R'$J7>EG:9MV7&2WY4E&Z:1$[)A;L\QQ +M@9PDVT&J1O\`NFUFEFFYI9.I%+?\85=ML^-T_P##/[K&W3U>?U'.IO`/T69> +MO\T/#I@<+7T4WTGM>\-<!(QNLKJ5!\%P@#OV73_*\TT\X\;T!2Z@^IOJS[[K +M*LVP!B#J6_XX:Y];.=(R>%S=*J]M00/RY/NN&/%T]TN\8WK<^EI<TNB%K6+V +MN+3!(`[K"LJKG-`.0=BM;I]0Z@20(A>G&N&3I>FO+;A@:YP&"(."NBMKJ:@; +M+=+<8*YKHU:=,P=(6E;^:UX>X`P9PMWAYLG46Q,B<M.1[)7]8,ID1I.V%1L; +M@AK9,\917-8UKAK6F8=)@%8L)?BYTR6TA+8<[)5@@NR<SQV5:A5DP9AN%8ID +MEATX6=-2HJ;=-WJ/!6C1,CZ+.>?YD.:<G>5=M7%D#@H;'6UBF2=O90522PQO +M&P5BK4EL$*O6)R-(AR+L]&12C:5E^(7PRF`[=X!$;Y6C.BC)9!]C,K)O#YE7 +M46R`X1/=3+IFV.SZ"7'H]$$02!CA7*P+J7T5;H'_`.44]P(5UP::6VZY3MSP +MJC5;#Q,#B945>D#D;=E<(!(&)35F12F1]%T=]N8Z[9BI,M&W*Y:Z;4MK@B3H +M:X;KT"ZH!U-Q+<KENOV;2UX#2!*DOK5LE=/X#ZF&T:;=63&)7HG2[EKZ33(S +M[KPSP[U#^'NPR'-CNO4_"M^*MNPZAMRNV4W'*<73MK>J(`!D[X4XJ$C$A9-K +M7Q\8PKC*DLP9D+C765?H7!:[2=CRK]O5&D#NL4/`$SE6K.YAP`4:VU]6(E-N +M#PH*+PX27$`YW4@>"["S6Y456F223A9G5VC0["U:SN%E]0<'5`SDE016E/3; +M"!&.Z&H-1DC?=6PS32;.T0HG!H<?\TA5"HT:H`V]U7K,W)P>RT*K?48C?ZJ* +MM3EL@_,J[33*?3.K41"*G6=3J`M5FK3(SLJSQ`WRK*EC9Z;?D:6..8W6S;7; +M2!#IGW7&4ZFDB)'LK]M=EH&8@)4G#I;JN#2)D#ZJWTJN/(&09]UR]3J`>UK- +M6^`MSI&;=N8E2\++MK^=VVV1LK>KC*H.<X")QV0FJ01+I4;:1JC$;]D+JA._ +M[J@;@-<&NJ-DG`E$:GJW'S*`>IU/1NAZ62*8,[E5NIU"6&"$73'N=2:`=^4J +M1K4ZO!/ZHV5H'YC$JD"<P90&JX$RD%\5B[,H75M+M_NJ3*CBZ)PE5<X@Y&%5 +M7*E8%D;K'ZC7!J1/*F=4=P5FWM7^<)G!V4O2?6I0J#R1C]4G%N_'*K47#R@0 +M>)"/6",G=1I*7[ANZ1=&5`7PW!A(O^I518;5)[(M6TE56N``(")M01ML@N!P +M@0=TXRV9"K!\B$8?!03AS28!D]D;2.3]%5UQSGV1!Y@[_P":H74'?RS$=H45 +MBXMIP"`=U'?/EARFLG2W$B$OPBTY\&-^4P=F4$CG?N@U0X[0B++7$'Y2>[B5 +M`U_<)R\[$G"HDJ.(;,IZ;QIB,PH''N8RE3)F)*@G#R3'',*<&6B`53U28W^B +ME;4<&C*HK=5!:=4;*6SJAUL#]"HNI^JD>?[*'IK_`$P3LE2+-5^<?,RF:<@G +M=!4(U'GV3-B-U055Q+C!PA!`;G=*<!,XB<G*(,/.G;<('@<G=(.`$S,>ZAJN +M$$QE6%!4_.<X]U7J.;J)DQSE'4)+]XGA152V8G9:95.K--6T<`($8[E972GQ +MKIG:=I6U<^J@0(_NL"B2SJ+VD[DI>CZOUI`(!PJ542\R(5QS<;Y*IW1C$F=E +M652NS\QF>5%2=#H.WRK#SCW5:!)SLBCK-;HB9"INC.^^59>3IWSL0H:[=+"1 +M^Z(K5(/YLK)NJIHWIIZ1I>9)T@G[Q*UZPEL3GV67UNBXT!4$XSNEG&EG%3R" +MT%G92VY)!(WXA4[.MKMF'^IHC=3VKH):5)>%URL!S>93ZF^ZCAO8E*&]BG#; +MSU].##9PH:E%AR>-YQ*NG<J/AWPFWGLURX7Q'T]MS6N',88:#.%PUQ;BG7<U +MP.Y^B]-J?^WN_P#\2\_ZO_[I_P`KCEQD]OBN\0].AKH)P1NM6T(UM:`2%E6W +MYA\K4L_R!=I4LVZ3HWDMI:P7:B(&<#Y6[TP4_+&LDEQX,RL#I7Y`NCZ?_P`T +M?"Z6O)FN>7%+6#('TE0=*+_.?4<##R0`<PKM/_V[_A5+7_V_W6-\Z9G3086B +M7%P@[@*]9AKFB(G>5E'\K?A:5CO]%?B]4]=O\V3NK%$0S)GLJ];=6:/Y6_19 +MC6^3U`00.Z3@=6G.VZ=WYDF_\QORFC?*&^;IHR"1'M*RJM)PI"I/YGXE:W5/ +M^0LZO_[+_P#&%G*_$RX==T)I;TFG)G&5=R:>TJGT7_\`+6?`_966;!8P[KEC +M"PT^Y4PIZJ$]U!5W5NG_`,KZ+HZJ5:B13.096%U2U+R8`RNDK?\`*/RLFZV* +MS>G2.#ZO;.MK[S`3`,KJO!?5X;387Q[2L+Q9_P"X8@\'?\_ZKKX[PQGC]>Q= +M&O&U*;3KS&RV:%0:1ZOU7(^'/RM736WY&K.4Y7%?U%WI_9)KG-=$_5#;[!)_ +MY'+G6XT+2O,`NV]U=8_TR#ORL:WV/PM*A_R6I5B6I4'EJA3FK>DQLK5S_P`L +MJ/IGYS\KG;J-3E.6C1![1"@>V1&_NK+]C\J`_F5-*[VD/.,;[H'@.:0)^B.X +M_*F=_P`GZ(:5*U,M!Q/RJE5AR5H5/RGZ*H[^KZIM*I5&&<843JKV'NK=;\BI +MW'YEK:6!97?_`!5/W*[/I%QIM&#&RX1O_O&?*Z[IO_MF_16I.&UYX+2F+F$` +MJK3_`.2/E)OY?J5C36UN*<C(U)Y^L*&G^9ORB'YOJ4L:5;]I<TY.^REZ;(IY +M,*.[Y16FP^%/HO!TXGZI1G*C9^<IV[JU(,``R("8D:D)V1'<?"BHZ\"7+%O7 +M`W7"V7_E6#=?^^<K>D^K]*I#!&Z/63_4HJ?_`"_HC;^8_`5THR\8@)]<[2@& +M[OA*EL4T"-4#&X"0>.^_91'_`)A3MW;\J"PUY`B81!Y.02H'?\M'0V^B"5KB +M#*E;4QO!]E`/S?1,W<J]ANH/&G=/TXQ3,S]5!>?F^BDZ?^1+\2+#R4QC5,IG +M[_5#4_YGV5@<.`,GZ(I,@]U$/^8%,>/HJD,YQWDIVNS$H*WY/JDS\P45('>K +M!PI`YI&V-L*!OYDXW*J&OS%$MD0JG3':JQ$JS=_^V<J?2_\`W04I%UY_F8(3 +M.=&1V2J_G*&K_P`L*@P_T=IY0.B<F)3-_($]7=JJ%,"%%5<'-@2"B?\`D4#O +MS'X50%0D=_E!4=+4]3\H^4Q_*541.,MX*P.I`T>HM?L"<RM]NRP_$G_-^H5^ +M)]6`Z6`MSB5%<`NSS"*V_P#;,^$U;=2=(IOB8^JJ/<6U<#G=6G_\PJI=_F"T +MARYK21.ZA<09`4K?Z5'<_D*;57J-QMD=U!<L\R@ZF>5/PAY*#%LIIWCJ)(`) +I("O4!#X(DJA<_P#YE_\`B6G2_P">U9ZNFXE:#I_,$^EW^,*4;)(T_]EK +` +end + + diff --git a/rt/sbin/extract-message-catalog b/rt/sbin/extract-message-catalog index af7b2c733..a7ba6335c 100644 --- a/rt/sbin/extract-message-catalog +++ b/rt/sbin/extract-message-catalog @@ -41,7 +41,7 @@ $DEBUG = 1; $FILECAT = {}; # extract all strings and stuff them into $FILECAT -File::Find::find( { wanted => \&extract_strings_from_code, follow => 0 }, '.' ); +File::Find::find( { wanted => \&extract_strings_from_code, follow => 1 }, '.' ); # ensure proper escaping and [_1] => %1 transformation foreach my $str ( sort keys %{$FILECAT} ) { diff --git a/rt/sbin/factory b/rt/sbin/factory index 8abb1922f..64b0ae337 100644 --- a/rt/sbin/factory +++ b/rt/sbin/factory @@ -61,6 +61,7 @@ my $LicenseBlock = << '.'; # # # END LICENSE BLOCK + . my $Attribution = << '.'; diff --git a/rt/sbin/license_tag b/rt/sbin/license_tag index 33da2e026..689b246ef 100644 --- a/rt/sbin/license_tag +++ b/rt/sbin/license_tag @@ -5,7 +5,7 @@ # # Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (Except where explicitly superseded by other copyright notices) # # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have @@ -29,7 +29,7 @@ my $LICENSE = <<EOL; Copyright (c) 1996-2003 Jesse Vincent <jesse\@bestpractical.com> -(Except where explictly superceded by other copyright notices) +(Except where explicitly superseded by other copyright notices) This work is made available to you under the terms of Version 2 of the GNU General Public License. A copy of that license should have @@ -57,7 +57,7 @@ File::Find::find({ no_chdir => 1, wanted => \&tag_pm}, 'lib'); File::Find::find({ no_chdir => 1, wanted => \&tag_mason}, 'html'); File::Find::find({ no_chdir => 1, wanted => \&tag_script}, 'sbin'); File::Find::find({ no_chdir => 1, wanted => \&tag_script}, 'bin'); -tag_makefile ('Makefile'); +tag_makefile ('Makefile.in'); tag_makefile ('README'); diff --git a/rt/sbin/rt-setup-database b/rt/sbin/rt-setup-database index f84f290b7..58f882f6e 100644 --- a/rt/sbin/rt-setup-database +++ b/rt/sbin/rt-setup-database @@ -80,7 +80,12 @@ if ( $args{'action'} eq 'init' ) { $dbh = DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} ) || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr"; print "Now creating a database for RT.\n"; + if ($RT::DatabaseType ne 'Oracle' || + $args{'dba'} ne $RT::DatabaseUser) { create_db(); + } else { + print "...skipped as ".$args{'dba'} ." is not " . $RT::DatabaseUser . " or we're working with Oracle.\n"; + } $dbh->disconnect; $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} ) @@ -89,7 +94,7 @@ if ( $args{'action'} eq 'init' ) { print "Now populating database schema.\n"; insert_schema(); print "Now inserting database ACLs\n"; - insert_acl(); + insert_acl() unless ($RT::DatabaseType eq 'Oracle'); print "Now inserting RT core system objects\n"; insert_initial_data(); print "Now inserting RT data\n"; @@ -137,8 +142,9 @@ sub insert_schema { open( SCHEMA_LOCAL, "<" . $RT::LocalEtcPath . "/schema." . $RT::DatabaseType ); my $statement = ""; - foreach my $line (<SCHEMA>, <SCHEMA_LOCAL>) { + foreach my $line (<SCHEMA>, ($_ = ';;'), <SCHEMA_LOCAL>) { $line =~ s/\#.*//g; + $line =~ s/--.*//g; $statement .= $line; if ( $line =~ /;(\s*)$/ ) { $statement =~ s/;(\s*)$//g; @@ -147,10 +153,13 @@ sub insert_schema { } } + local $SIG{__WARN__} = sub {}; + my $is_local = 0; # local/etc/schema needs to be nonfatal. foreach my $statement (@schema) { - print STDERR $statement if $args{'debug'}; + if ($statement =~ /^\s*;$/) { $is_local = 1; next; } + print STDERR "SQL: $statement\n" if defined $args{'debug'}; my $sth = $dbh->prepare($statement) or die $dbh->errstr; - unless ( $sth->execute ) { + unless ( $sth->execute or $is_local ) { die "Problem with statement:\n $statement\n" . $sth->errstr; } } @@ -168,6 +177,16 @@ sub insert_schema { # {{{ sub drop_db sub drop_db { return if ( $RT::DatabaseType eq 'SQLite' ); + if ( $RT::DatabaseType eq 'Oracle' ) { + print <<END; + +To delete the tables and sequences of the RT Oracle database by running + \@etc/drop.Oracle +through SQLPlus. + +END + return; + } unless ( $args{'force'} ) { print <<END; @@ -198,6 +217,13 @@ sub create_db { $dbh->do("CREATE DATABASE $RT::DatabaseName") || die $DBI::errstr; } } + elsif ($RT::DatabaseType eq 'Oracle') { + insert_acl(); + } + elsif ( $RT::DatabaseType eq 'Informix' ) { + $ENV{DB_LOCALE} = 'en_us.utf8'; + $dbh->do("CREATE DATABASE $RT::DatabaseName WITH BUFFERED LOG"); + } else { $dbh->do("CREATE DATABASE $RT::DatabaseName") or die $DBI::errstr; } @@ -248,6 +274,10 @@ sub insert_acl { do $base_path . "/acl.mysql" || die "Couldn't find ACLS for mysql in " . $RT::EtcPath . "\n" . $@; } + elsif ( $RT::DatabaseType =~ /^informix$/i ) { + do $base_path . "/acl.Informix" + || die "Couldn't find ACLS for Informix in " . $RT::EtcPath . "\n" . $@; + } elsif ( $RT::DatabaseType =~ /^SQLite$/i ) { return; } @@ -287,6 +317,10 @@ sub get_system_dsn { elsif ( $RT::DatabaseType eq 'Pg' ) { $dsn =~ s/dbname=$RT::DatabaseName/dbname=template1/; } + elsif ( $RT::DatabaseType eq 'Informix' ) { + # with Informix, you want to connect sans database: + $dsn =~ s/Informix:$RT::DatabaseName/Informix:/; + } return $dsn; } @@ -302,7 +336,7 @@ sub insert_initial_data { #Put together a current user object so we can create a User object my $CurrentUser = new RT::CurrentUser(); - print "Checking for existing system user..."; + print "Checking for existing system user ($CurrentUser)..."; my $test_user = RT::User->new($CurrentUser); $test_user->Load('RT_System'); if ( $test_user->id ) { @@ -330,7 +364,7 @@ sub insert_initial_data { exit(1); } print "done.\n"; - $RT::Handle->dbh->disconnect(); + $RT::Handle->Disconnect(); } diff --git a/rt/sbin/rt-setup-database.in b/rt/sbin/rt-setup-database.in index e49a32ed9..9e990e5b8 100644 --- a/rt/sbin/rt-setup-database.in +++ b/rt/sbin/rt-setup-database.in @@ -80,7 +80,12 @@ if ( $args{'action'} eq 'init' ) { $dbh = DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} ) || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr"; print "Now creating a database for RT.\n"; + if ($RT::DatabaseType ne 'Oracle' || + $args{'dba'} ne $RT::DatabaseUser) { create_db(); + } else { + print "...skipped as ".$args{'dba'} ." is not " . $RT::DatabaseUser . " or we're working with Oracle.\n"; + } $dbh->disconnect; $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} ) @@ -89,7 +94,7 @@ if ( $args{'action'} eq 'init' ) { print "Now populating database schema.\n"; insert_schema(); print "Now inserting database ACLs\n"; - insert_acl(); + insert_acl() unless ($RT::DatabaseType eq 'Oracle'); print "Now inserting RT core system objects\n"; insert_initial_data(); print "Now inserting RT data\n"; @@ -137,8 +142,9 @@ sub insert_schema { open( SCHEMA_LOCAL, "<" . $RT::LocalEtcPath . "/schema." . $RT::DatabaseType ); my $statement = ""; - foreach my $line (<SCHEMA>, <SCHEMA_LOCAL>) { + foreach my $line (<SCHEMA>, ($_ = ';;'), <SCHEMA_LOCAL>) { $line =~ s/\#.*//g; + $line =~ s/--.*//g; $statement .= $line; if ( $line =~ /;(\s*)$/ ) { $statement =~ s/;(\s*)$//g; @@ -147,10 +153,13 @@ sub insert_schema { } } + local $SIG{__WARN__} = sub {}; + my $is_local = 0; # local/etc/schema needs to be nonfatal. foreach my $statement (@schema) { - print STDERR $statement if $args{'debug'}; + if ($statement =~ /^\s*;$/) { $is_local = 1; next; } + print STDERR "SQL: $statement\n" if defined $args{'debug'}; my $sth = $dbh->prepare($statement) or die $dbh->errstr; - unless ( $sth->execute ) { + unless ( $sth->execute or $is_local ) { die "Problem with statement:\n $statement\n" . $sth->errstr; } } @@ -168,6 +177,16 @@ sub insert_schema { # {{{ sub drop_db sub drop_db { return if ( $RT::DatabaseType eq 'SQLite' ); + if ( $RT::DatabaseType eq 'Oracle' ) { + print <<END; + +To delete the tables and sequences of the RT Oracle database by running + \@etc/drop.Oracle +through SQLPlus. + +END + return; + } unless ( $args{'force'} ) { print <<END; @@ -198,6 +217,13 @@ sub create_db { $dbh->do("CREATE DATABASE $RT::DatabaseName") || die $DBI::errstr; } } + elsif ($RT::DatabaseType eq 'Oracle') { + insert_acl(); + } + elsif ( $RT::DatabaseType eq 'Informix' ) { + $ENV{DB_LOCALE} = 'en_us.utf8'; + $dbh->do("CREATE DATABASE $RT::DatabaseName WITH BUFFERED LOG"); + } else { $dbh->do("CREATE DATABASE $RT::DatabaseName") or die $DBI::errstr; } @@ -248,6 +274,10 @@ sub insert_acl { do $base_path . "/acl.mysql" || die "Couldn't find ACLS for mysql in " . $RT::EtcPath . "\n" . $@; } + elsif ( $RT::DatabaseType =~ /^informix$/i ) { + do $base_path . "/acl.Informix" + || die "Couldn't find ACLS for Informix in " . $RT::EtcPath . "\n" . $@; + } elsif ( $RT::DatabaseType =~ /^SQLite$/i ) { return; } @@ -287,6 +317,10 @@ sub get_system_dsn { elsif ( $RT::DatabaseType eq 'Pg' ) { $dsn =~ s/dbname=$RT::DatabaseName/dbname=template1/; } + elsif ( $RT::DatabaseType eq 'Informix' ) { + # with Informix, you want to connect sans database: + $dsn =~ s/Informix:$RT::DatabaseName/Informix:/; + } return $dsn; } @@ -302,7 +336,7 @@ sub insert_initial_data { #Put together a current user object so we can create a User object my $CurrentUser = new RT::CurrentUser(); - print "Checking for existing system user..."; + print "Checking for existing system user ($CurrentUser)..."; my $test_user = RT::User->new($CurrentUser); $test_user->Load('RT_System'); if ( $test_user->id ) { @@ -330,7 +364,7 @@ sub insert_initial_data { exit(1); } print "done.\n"; - $RT::Handle->dbh->disconnect(); + $RT::Handle->Disconnect(); } diff --git a/rt/sbin/rt-test-dependencies b/rt/sbin/rt-test-dependencies index 637d33a32..c1591b189 100644 --- a/rt/sbin/rt-test-dependencies +++ b/rt/sbin/rt-test-dependencies @@ -36,10 +36,14 @@ my %args; my %deps; GetOptions(\%args,'install', 'with-MYSQL', 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE', 'with-ORACLE', 'with-FASTCGI', 'with-SPEEDYCGI', 'with-MODPERL1', 'with-MODPERL2' ,'with-DEV'); -if (!keys %args) { -help(); -exit(0); +if (!keys %args) { + help(); + exit(0); +} +if ($args{'with-MODPERL2'}) { + warn_modperl2(); } + $args{'with-MASON'} = 1; $args{'with-CORE'} = 1; $args{'with-DEV'} =1; @@ -49,10 +53,20 @@ if ($] < 5.007) { $args{'with-I18N-COMPAT'} = 1; } +sub warn_modperl2 { + print <<'.'; + NOTE: mod_perl 2.0 isn't quite ready for prime_time just yet; + Best Practical Solutions strongly recommends that sites use + Apache 1.3 or FastCGI. If you MUST use mod_perl 2.0 (or 1.99), + please read the mailing list archives before asking for help. +. + sleep 5; +} + sub help { -print <<'.' + print <<'.'; By default, testdeps determine whether you have installed all the perl modules RT needs to run. @@ -81,18 +95,18 @@ sub _ { } $deps{'CORE'} = [ _( << '.') ]; -Digest::MD5 -DBI 1.18 +Digest::MD5 2.27 +DBI 1.37 Test::Inline Class::ReturnValue 0.40 -DBIx::SearchBuilder 0.86 +DBIx::SearchBuilder 0.97 Text::Template File::Spec 0.8 HTML::Entities Net::Domain Log::Dispatch 2.0 -Locale::Maketext 1.04 -Locale::Maketext::Lexicon 0.25 +Locale::Maketext 1.06 +Locale::Maketext::Lexicon 0.32 Locale::Maketext::Fuzzy MIME::Entity 5.108 Mail::Mailer 1.57 @@ -102,7 +116,8 @@ Time::ParseDate File::Temp Term::ReadKey Text::Autoformat -Text::Quoted +Text::Quoted 1.3 +Scalar::Util . $deps{'MASON'} = [ _( << '.') ]; @@ -113,9 +128,9 @@ HTML::Mason 1.16 MLDBM Errno FreezeThaw -Digest::MD5 +Digest::MD5 2.27 CGI::Cookie 1.20 -Storable +Storable 2.08 Apache::Session 1.53 . @@ -138,25 +153,25 @@ WWW::Mechanize . $deps{'FASTCGI'} = [ _( << '.') ]; -CGI +CGI 2.92 FCGI CGI::Fast . $deps{'SPEEDYCGI'} = [ _( << '.') ]; -CGI +CGI 2.92 CGI::SpeedyCGI . $deps{'MODPERL1'} = [ _( << '.') ]; -CGI +CGI 2.92 Apache::Request -Apache::DBI +Apache::DBI 0.92 . $deps{'MODPERL2'} = [ _( << '.') ]; -CGI 2.89 +CGI 2.92 Apache::DBI . @@ -175,6 +190,23 @@ $deps{'POSTGRESQL'} = [ _( << '.') ]; DBD::Pg . +print "perl:\n"; +print "\t5.8.0"; +eval {require 5.008}; +if ($@) { +print "...missing.\n"; + eval {require 5.006001}; + if ($@) { + print " RT is known to be non-functional on versions of perl older than 5.6.1. Please upgrade to 5.8.0 or newer"; + die; + } else { + print " RT is not supported on perl 5.6.1\n"; + } +} else { + print "...found\n"; + +} + foreach my $type (keys %args) { next unless ($type =~ /^with-(.*?)$/); @@ -196,17 +228,17 @@ sub test_dep { my $module = shift; my $version = shift; - print "\t$module $version"; - eval "use $module $version" ; - if ($@) { - my $error = $@; - $error =~ s/\n(.*)$//s; - print "...MISSING\n"; - print "\t\t$error\n" if $error =~ /this is only/; + print "\t$module $version"; + eval "use $module $version" ; + if ($@) { + my $error = $@; + $error =~ s/\n(.*)$//s; + print "...MISSING\n"; + print "\t\t$error\n" if $error =~ /this is only/; - return undef; + return undef; } else { - print "...found\n"; + print "...found\n"; return 1; } } diff --git a/rt/sbin/rt-test-dependencies.in b/rt/sbin/rt-test-dependencies.in index 6951290c4..7a1508010 100644 --- a/rt/sbin/rt-test-dependencies.in +++ b/rt/sbin/rt-test-dependencies.in @@ -36,10 +36,14 @@ my %args; my %deps; GetOptions(\%args,'install', 'with-MYSQL', 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE', 'with-ORACLE', 'with-FASTCGI', 'with-SPEEDYCGI', 'with-MODPERL1', 'with-MODPERL2' ,'with-DEV'); -if (!keys %args) { -help(); -exit(0); +if (!keys %args) { + help(); + exit(0); +} +if ($args{'with-MODPERL2'}) { + warn_modperl2(); } + $args{'with-MASON'} = 1; $args{'with-CORE'} = 1; $args{'with-DEV'} =1; @@ -49,10 +53,20 @@ if ($] < 5.007) { $args{'with-I18N-COMPAT'} = 1; } +sub warn_modperl2 { + print <<'.'; + NOTE: mod_perl 2.0 isn't quite ready for prime_time just yet; + Best Practical Solutions strongly recommends that sites use + Apache 1.3 or FastCGI. If you MUST use mod_perl 2.0 (or 1.99), + please read the mailing list archives before asking for help. +. + sleep 5; +} + sub help { -print <<'.' + print <<'.'; By default, testdeps determine whether you have installed all the perl modules RT needs to run. @@ -81,18 +95,18 @@ sub _ { } $deps{'CORE'} = [ _( << '.') ]; -Digest::MD5 -DBI 1.18 +Digest::MD5 2.27 +DBI 1.37 Test::Inline Class::ReturnValue 0.40 -DBIx::SearchBuilder 0.86 +DBIx::SearchBuilder 0.97 Text::Template File::Spec 0.8 HTML::Entities Net::Domain Log::Dispatch 2.0 -Locale::Maketext 1.04 -Locale::Maketext::Lexicon 0.25 +Locale::Maketext 1.06 +Locale::Maketext::Lexicon 0.32 Locale::Maketext::Fuzzy MIME::Entity 5.108 Mail::Mailer 1.57 @@ -102,7 +116,8 @@ Time::ParseDate File::Temp Term::ReadKey Text::Autoformat -Text::Quoted +Text::Quoted 1.3 +Scalar::Util . $deps{'MASON'} = [ _( << '.') ]; @@ -113,9 +128,9 @@ HTML::Mason 1.16 MLDBM Errno FreezeThaw -Digest::MD5 +Digest::MD5 2.27 CGI::Cookie 1.20 -Storable +Storable 2.08 Apache::Session 1.53 . @@ -138,25 +153,25 @@ WWW::Mechanize . $deps{'FASTCGI'} = [ _( << '.') ]; -CGI +CGI 2.92 FCGI CGI::Fast . $deps{'SPEEDYCGI'} = [ _( << '.') ]; -CGI +CGI 2.92 CGI::SpeedyCGI . $deps{'MODPERL1'} = [ _( << '.') ]; -CGI +CGI 2.92 Apache::Request -Apache::DBI +Apache::DBI 0.92 . $deps{'MODPERL2'} = [ _( << '.') ]; -CGI 2.89 +CGI 2.92 Apache::DBI . @@ -175,6 +190,23 @@ $deps{'POSTGRESQL'} = [ _( << '.') ]; DBD::Pg . +print "perl:\n"; +print "\t5.8.0"; +eval {require 5.008}; +if ($@) { +print "...missing.\n"; + eval {require 5.006001}; + if ($@) { + print " RT is known to be non-functional on versions of perl older than 5.6.1. Please upgrade to 5.8.0 or newer"; + die; + } else { + print " RT is not supported on perl 5.6.1\n"; + } +} else { + print "...found\n"; + +} + foreach my $type (keys %args) { next unless ($type =~ /^with-(.*?)$/); @@ -196,17 +228,17 @@ sub test_dep { my $module = shift; my $version = shift; - print "\t$module $version"; - eval "use $module $version" ; - if ($@) { - my $error = $@; - $error =~ s/\n(.*)$//s; - print "...MISSING\n"; - print "\t\t$error\n" if $error =~ /this is only/; + print "\t$module $version"; + eval "use $module $version" ; + if ($@) { + my $error = $@; + $error =~ s/\n(.*)$//s; + print "...MISSING\n"; + print "\t\t$error\n" if $error =~ /this is only/; - return undef; + return undef; } else { - print "...found\n"; + print "...found\n"; return 1; } } |