Changeset 411 for WizardsToolkit/trunk
- Timestamp:
- 10/18/09 19:17:20 (5 weeks ago)
- Location:
- WizardsToolkit/trunk
- Files:
-
- 15 modified
-
config/configure.xml (modified) (1 diff)
-
wizard/log.c (modified) (3 diffs)
-
wizard/log.h (modified) (2 diffs)
-
wizard/mime.c (modified) (3 diffs)
-
wizard/mime.h (modified) (2 diffs)
-
wizard/nt-base.c (modified) (1 diff)
-
wizard/random.c (modified) (2 diffs)
-
wizard/random_.h (modified) (1 diff)
-
wizard/resource.c (modified) (6 diffs)
-
wizard/resource_.h (modified) (2 diffs)
-
wizard/semaphore.c (modified) (14 diffs)
-
wizard/semaphore.h (modified) (1 diff)
-
wizard/thread.c (modified) (1 diff)
-
wizard/version.h (modified) (1 diff)
-
wizard/wizard.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
WizardsToolkit/trunk/config/configure.xml
r386 r411 18 18 <configure name="LIB_VERSION" value="0x107" /> 19 19 <configure name="LIB_VERSION_NUMBER" value="1,0,7,0" /> 20 <configure name="RELEASE_DATE" value="2009-10-1 5" />20 <configure name="RELEASE_DATE" value="2009-10-18" /> 21 21 <configure name="COPYRIGHT" value="Copyright (C) 1999-2009 ImageMagick Studio LLC" /> 22 22 <configure name="WEBSITE" value="http://www.wizards-toolkit.org" /> -
WizardsToolkit/trunk/wizard/log.c
r242 r411 231 231 % % 232 232 % % 233 + D e s t r o y L o g L i s t%234 % % 235 % % 236 % % 237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 238 % 239 % DestroyLog List() deallocates memory associated with the log list.240 % 241 % The format of the DestroyLog Listmethod is:242 % 243 % DestroyLog List(void)233 + D e s t r o y L o g F a c i l i t y % 234 % % 235 % % 236 % % 237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 238 % 239 % DestroyLogFacility() destroys the log facility. 240 % 241 % The format of the DestroyLogFacility method is: 242 % 243 % DestroyLogFacility(void) 244 244 % 245 245 */ … … 270 270 } 271 271 272 WizardExport void DestroyLog List(void)272 WizardExport void DestroyLogFacility(void) 273 273 { 274 274 AcquireSemaphoreInfo(&log_semaphore); … … 588 588 } 589 589 return(log_list != (LinkedListInfo *) NULL ? WizardTrue : WizardFalse); 590 } 591 592 /* 593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 594 % % 595 % % 596 % % 597 + I n s t a n t i a t e L o g F a c i l i t y % 598 % % 599 % % 600 % % 601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 602 % 603 % InstantiateLogFacility() instantiates the log facility. 604 % 605 % The format of the InstantiateLogFacility method is: 606 % 607 % WizardBooleanType InstantiateLogFacility(void) 608 % 609 */ 610 WizardExport WizardBooleanType InstantiateLogFacility(void) 611 { 612 AcquireSemaphoreInfo(&log_semaphore); 613 RelinquishSemaphoreInfo(log_semaphore); 614 return(WizardFalse); 590 615 } 591 616 -
WizardsToolkit/trunk/wizard/log.h
r1 r411 68 68 69 69 extern WizardExport WizardBooleanType 70 InstantiateLogFacility(void), 70 71 IsEventLogging(void), 71 72 ListLogInfo(FILE *,ExceptionInfo *), … … 79 80 extern WizardExport void 80 81 CloseWizardLog(void), 81 DestroyLog List(void),82 DestroyLogFacility(void), 82 83 SetLogFormat(const char *), 83 84 SetLogPreamble(const char *); -
WizardsToolkit/trunk/wizard/mime.c
r1 r411 132 132 % % 133 133 % % 134 + D e s t r o y M i m e L i s t%135 % % 136 % % 137 % % 138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 139 % 140 % DestroyMime List() deallocates memory associated with the mime list.141 % 142 % The format of the DestroyMime Listmethod is:143 % 144 % DestroyMime List(void)134 + D e s t r o y M i m e F a c i l i t y % 135 % % 136 % % 137 % % 138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 139 % 140 % DestroyMimeFacility() destroys the mime facility. 141 % 142 % The format of the DestroyMimeFacility method is: 143 % 144 % DestroyMimeFacility(void) 145 145 % 146 146 */ … … 166 166 } 167 167 168 WizardExport void DestroyMime List(void)168 WizardExport void DestroyMimeFacility(void) 169 169 { 170 170 AcquireSemaphoreInfo(&mime_semaphore); … … 671 671 % % 672 672 % % 673 + I n s t a n t i a t e M i m e F a c i l i t y % 674 % % 675 % % 676 % % 677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 678 % 679 % InstantiateMimeFacility() instantiates the mime facility. 680 % 681 % The format of the InstantiateMimeFacility method is: 682 % 683 % WizardBooleanType InstantiateMimeFacility(void) 684 % 685 */ 686 WizardExport WizardBooleanType InstantiateMimeFacility(void) 687 { 688 AcquireSemaphoreInfo(&mime_semaphore); 689 RelinquishSemaphoreInfo(mime_semaphore); 690 return(WizardTrue); 691 } 692 693 /* 694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 695 % % 696 % % 697 % % 673 698 % L i s t M i m e I n f o % 674 699 % % -
WizardsToolkit/trunk/wizard/mime.h
r1 r411 35 35 36 36 extern WizardExport WizardBooleanType 37 InstantiateMimeFacility(void), 37 38 ListMimeInfo(FILE *,ExceptionInfo *), 38 39 LoadMimeLists(const char *,ExceptionInfo *); … … 43 44 44 45 extern WizardExport void 45 DestroyMime List(void);46 DestroyMimeFacility(void); 46 47 47 48 #if defined(__cplusplus) || defined(c_plusplus) -
WizardsToolkit/trunk/wizard/nt-base.c
r1 r411 330 330 static BOOL ControlHandler(DWORD type) 331 331 { 332 AsynchronousDestroy WizardResources();332 AsynchronousDestroyResourceFacility(); 333 333 return(FALSE); 334 334 } -
WizardsToolkit/trunk/wizard/random.c
r238 r411 306 306 % % 307 307 % % 308 + D e s t r o y R a n d o m R e s e r v i o r % 309 % % 310 % % 311 % % 312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 313 % 314 % DestroyRandomReservoir() deallocates memory associated with the random 315 % reservoir. 316 % 317 % The format of the DestroyRandomReservoir method is: 318 % 319 % DestroyRandomReservoir(void) 320 % 321 */ 322 WizardExport void DestroyRandomReservoir(void) 308 + D e s t r o y R a n d o m F a c i l i t y % 309 % % 310 % % 311 % % 312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 313 % 314 % DestroyRandomFacility() destroys the random facility. 315 % 316 % The format of the DestroyRandomFacility method is: 317 % 318 % DestroyRandomFacility(void) 319 % 320 */ 321 WizardExport void DestroyRandomFacility(void) 323 322 { 324 323 AcquireSemaphoreInfo(&random_semaphore); … … 776 775 % % 777 776 % % 777 + I n s t a n t i a t e R a n d o m F a c i l i t y % 778 % % 779 % % 780 % % 781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 782 % 783 % InstantiateRandomFacility() instantiates the random facility. 784 % 785 % The format of the InstantiateRandomFacility method is: 786 % 787 % InstantiateRandomFacility(void) 788 % 789 */ 790 WizardExport WizardBooleanType InstantiateRandomFacility(void) 791 { 792 AcquireSemaphoreInfo(&random_semaphore); 793 RelinquishSemaphoreInfo(random_semaphore); 794 return(WizardTrue); 795 } 796 797 /* 798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 799 % % 800 % % 801 % % 778 802 % G e t P s e u d o R a n d o m V a l u e % 779 803 % % -
WizardsToolkit/trunk/wizard/random_.h
r1 r411 46 46 47 47 extern WizardExport void 48 DestroyRandom Reservoir(void),48 DestroyRandomFacility(void), 49 49 SeedPseudoRandomGenerator(const unsigned long), 50 50 SetRandomKey(RandomInfo *,const size_t,unsigned char *), 51 51 SetRandomTrueRandom(const WizardBooleanType); 52 53 extern WizardExport WizardBooleanType 54 InstantiateRandomFacility(void); 52 55 53 56 #if defined(__cplusplus) || defined(c_plusplus) -
WizardsToolkit/trunk/wizard/resource.c
r232 r411 449 449 % % 450 450 % % 451 + A s y n c h r o n o u s D e s t r o y W i z a r d R e s o u r c e s%452 % % 453 % % 454 % % 455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 456 % 457 % AsynchronousDestroy WizardResources() destroys the resource environment.458 % It differs from Destroy WizardResources() in that it can be called from a451 + A s y n c h r o n o u s D e s t r o y R e s o u r c e F a c i l i t y % 452 % % 453 % % 454 % % 455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 456 % 457 % AsynchronousDestroyResourceFacility() destroys the resource environment. 458 % It differs from DestroyResourceFacility() in that it can be called from a 459 459 % asynchronous signal handler. 460 460 % 461 % The format of the Destroy WizardResources() method is:462 % 463 % Destroy WizardResources(void)464 % 465 */ 466 WizardExport void AsynchronousDestroy WizardResources(void)461 % The format of the DestroyResourceFacility() method is: 462 % 463 % DestroyResourceFacility(void) 464 % 465 */ 466 WizardExport void AsynchronousDestroyResourceFacility(void) 467 467 { 468 468 const char … … 490 490 % % 491 491 % % 492 + D e s t r o y W i z a r d R e s o u r c e s%493 % % 494 % % 495 % % 496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 497 % 498 % Destroy WizardResources() destroys the resource environment.499 % 500 % The format of the Destroy WizardResources() method is:501 % 502 % Destroy WizardResources(void)503 % 504 */ 505 WizardExport void Destroy WizardResources(void)492 + D e s t r o y R e s o u r c e F a c i l i t y % 493 % % 494 % % 495 % % 496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 497 % 498 % DestroyResourceFacility() destroys the resource facility. 499 % 500 % The format of the DestroyResourceFacility() method is: 501 % 502 % DestroyResourceFacility(void) 503 % 504 */ 505 WizardExport void DestroyResourceFacility(void) 506 506 { 507 507 AcquireSemaphoreInfo(&resource_semaphore); … … 643 643 % % 644 644 % % 645 + I n i t i a l i z e W i z a r d R e s o u r c e s%646 % % 647 % % 648 % % 649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 650 % 651 % In itializeWizardResources() initializes the resource environment.652 % 653 % The format of the In itializeWizardResources()method is:654 % 655 % InitializeWizardResources(void)645 + I n s t a n t i a t e R e s o u r c e F a c i l i t y % 646 % % 647 % % 648 % % 649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 650 % 651 % InstantiateResourceFacility() instantiates the resource facility. 652 % 653 % The format of the InstantiateResourceFacility method is: 654 % 655 % WizardBooleanType InstantiateResourceFacility(void) 656 656 % 657 657 */ … … 664 664 } 665 665 666 WizardExport void InitializeWizardResources(void)666 WizardExport WizardBooleanType InstantiateResourceFacility(void) 667 667 { 668 668 char … … 680 680 Set Wizard resource limits. 681 681 */ 682 RelinquishSemaphoreInfo(resource_semaphore); 682 683 pagesize=(-1); 683 684 #if defined(WIZARDSTOOLKIT_HAVE_SYSCONF) && defined(_SC_PAGESIZE) … … 737 738 limit=DestroyString(limit); 738 739 } 740 AcquireSemaphoreInfo(&resource_semaphore); 741 return(WizardTrue); 739 742 } 740 743 -
WizardsToolkit/trunk/wizard/resource_.h
r1 r411 45 45 AcquireWizardResource(const ResourceType,const WizardSizeType), 46 46 AcquireUniqueFilename(char *,ExceptionInfo *), 47 InstantiateResourceFacility(void), 48 ListWizardResourceInfo(FILE *,ExceptionInfo *), 47 49 RelinquishUniqueFileResource(const char *,const WizardBooleanType), 48 ListWizardResourceInfo(FILE *,ExceptionInfo *),49 50 SetWizardResourceLimit(const ResourceType,const WizardSizeType); 50 51 … … 53 54 54 55 extern WizardExport void 55 AsynchronousDestroyWizardResources(void), 56 DestroyWizardResources(void), 57 InitializeWizardResources(void), 56 AsynchronousDestroyResourceFacility(void), 57 DestroyResourceFacility(void), 58 58 RelinquishWizardResource(const ResourceType,const WizardSizeType); 59 59 -
WizardsToolkit/trunk/wizard/semaphore.c
r359 r411 11 11 % % 12 12 % % 13 % Wizard's Toolkit Semaphore Methods%13 % WizardCore Semaphore Methods % 14 14 % % 15 15 % Software Design % 16 % William Radcliffe % 16 17 % John Cristy % 17 18 % June 2000 % … … 42 43 */ 43 44 #include "wizard/studio.h" 44 #include "wizard/client.h"45 45 #include "wizard/exception.h" 46 46 #include "wizard/exception-private.h" … … 82 82 semaphore_mutex = 0; 83 83 #endif 84 85 static WizardBooleanType 86 instantiate_semaphore = WizardFalse; 84 87 85 88 /* … … 138 141 % 139 142 % SemaphoreInfo *AllocateSemaphoreInfo(void) 140 %141 % A description of each parameter follows:142 %143 % o semaphore_info: Method AllocateSemaphoreInfo returns a pointer to an144 % initialized SemaphoreInfo structure.145 %146 143 % 147 144 */ … … 175 172 semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory( 176 173 semaphore_info); 177 return((SemaphoreInfo *) NULL); 174 ThrowFatalException(ResourceFatalError, 175 "unable to instantiate semaphore `%s'"); 178 176 } 179 177 status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info); … … 183 181 semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory( 184 182 semaphore_info); 185 return((SemaphoreInfo *) NULL); 183 ThrowFatalException(ResourceFatalError, 184 "unable to instantiate semaphore `%s'"); 186 185 } 187 186 } … … 217 216 #if defined(WIZARDSTOOLKIT_HAVE_PTHREAD) 218 217 if (pthread_mutex_destroy(&semaphore_mutex) != 0) 219 { 220 (void) fprintf(stderr,"pthread_mutex_destroy failed %s\n", 221 strerror(errno)); 222 _exit(1); 223 } 224 #endif 218 (void) fprintf(stderr,"pthread_mutex_destroy failed %s\n", 219 GetExceptionMessage(errno)); 220 #elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS) 221 if (instantiate_semaphore == WizardFalse) 222 DeleteCriticalSection(&semaphore_mutex); 223 #endif 224 instantiate_semaphore=WizardFalse; 225 225 } 226 226 … … 268 268 % % 269 269 % % 270 % I n i t i a l i z e S e m a p h o r e % 271 % % 272 % % 273 % % 274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 275 % 276 % InitializeSemaphore() initializes the semaphore environment. 277 % 278 % The format of the InitializeSemaphore method is: 279 % 280 % InitializeSemaphore(void) 281 % 282 */ 283 WizardExport void InitializeSemaphore(void) 284 { 285 } 286 287 /* 288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 289 % % 290 % % 291 % % 292 % L o c k W i z a r d M u t e x % 270 % I n s t a n t i a t e S e m a p h o r e % 271 % % 272 % % 273 % % 274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 275 % 276 % InstantiateSemaphore() instantiates the semaphore environment. 277 % 278 % The format of the InstantiateSemaphore method is: 279 % 280 % WizardBooleanType InstantiateSemaphore(void) 281 % 282 */ 283 WizardExport WizardBooleanType InstantiateSemaphore(void) 284 { 285 LockWizardMutex(); 286 UnlockWizardMutex(); 287 return(WizardTrue); 288 } 289 290 /* 291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 292 % % 293 % % 294 % % 295 + L o c k W i z a r d M u t e x % 293 296 % % 294 297 % % … … 304 307 % 305 308 */ 306 WizardExportvoid LockWizardMutex(void)309 static void LockWizardMutex(void) 307 310 { 308 311 #if defined(WIZARDSTOOLKIT_HAVE_PTHREAD) … … 311 314 GetExceptionMessage(errno)); 312 315 #elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS) 316 if (instantiate_semaphore == WizardFalse) 317 InitializeCriticalSection(&semaphore_mutex); 318 instantiate_semaphore=WizardTrue; 313 319 while (InterlockedCompareExchange(&semaphore_mutex,1L,0L) != 0) 314 320 Sleep(10); … … 372 378 (void) fflush(stderr); 373 379 } 374 semaphore_info->id=id;375 380 } 376 381 #endif … … 416 421 % % 417 422 % % 418 %U n l o c k W i z a r d M u t e x %423 + U n l o c k W i z a r d M u t e x % 419 424 % % 420 425 % % … … 429 434 % 430 435 */ 431 WizardExportvoid UnlockWizardMutex(void)436 static void UnlockWizardMutex(void) 432 437 { 433 438 #if defined(WIZARDSTOOLKIT_HAVE_PTHREAD) … … 468 473 assert(semaphore_info->signature == WizardSignature); 469 474 #if defined(WIZARDSTOOLKIT_DEBUG) 470 assert(Is SizeThreadEqual(semaphore_info->id) != WizardFalse);475 assert(IsWizardThreadEqual(semaphore_info->id) != WizardFalse); 471 476 if (semaphore_info->reference_count == 0) 472 477 { -
WizardsToolkit/trunk/wizard/semaphore.h
r1 r411 33 33 DestroySemaphore(void), 34 34 DestroySemaphoreInfo(SemaphoreInfo **), 35 InitializeSemaphore(void),36 35 RelinquishSemaphoreInfo(SemaphoreInfo *); 37 36 38 37 extern WizardExport WizardBooleanType 38 InstantiateSemaphore(void), 39 39 LockSemaphoreInfo(SemaphoreInfo *), 40 40 UnlockSemaphoreInfo(SemaphoreInfo *); -
WizardsToolkit/trunk/wizard/thread.c
r1 r411 65 65 { 66 66 #if defined(WIZARDSTOOLKIT_HAVE_PTHREAD) 67 return(pthread_key_create(key, (void *)NULL) == 0 ? WizardTrue : WizardFalse);67 return(pthread_key_create(key,NULL) == 0 ? WizardTrue : WizardFalse); 68 68 #elif defined(MAGICKORE_HAVE_WINTHREADS) 69 69 *key=TlsAlloc(); -
WizardsToolkit/trunk/wizard/version.h
r386 r411 32 32 #define WizardLibVersionNumber 1,0,1 33 33 #define WizardLibSubversion "-0" 34 #define WizardReleaseDate "2009-10-1 5"34 #define WizardReleaseDate "2009-10-18" 35 35 #define WizardChangeDate "20090428" 36 36 #define WizardAuthoritativeURL "http://www.wizards-toolkit.org" -
WizardsToolkit/trunk/wizard/wizard.c
r1 r411 153 153 (void) signal(signal_number,SIG_IGN); 154 154 #endif 155 AsynchronousDestroy WizardResources();155 AsynchronousDestroyResourceFacility(); 156 156 instantiate_wizard=WizardFalse; 157 157 (void) SetWizardSignalHandler(signal_number,signal_handlers[signal_number]); … … 215 215 (void) setlocale(LC_NUMERIC,"C"); 216 216 seconds=time((time_t *) NULL); 217 InitializeSemaphore(); 217 (void) InstantiateSemaphore(); 218 (void) InstantiateLogFacility(); 219 (void) InstantiateRandomFacility(); 218 220 events=GetEnvironmentValue("WIZARD_DEBUG"); 219 221 if (events != (char *) NULL) … … 292 294 Initialize wizard resources. 293 295 */ 294 InitializeWizardResources(); 296 (void) InstantiateResourceFacility(); 297 (void) InstantiateMimeFacility(); 295 298 } 296 299 … … 316 319 WizardExport void WizardsToolkitTerminus(void) 317 320 { 318 DestroyMime List();319 Destroy WizardResources();320 DestroyRandom Reservoir();321 DestroyLog List();322 } 321 DestroyMimeFacility(); 322 DestroyResourceFacility(); 323 DestroyRandomFacility(); 324 DestroyLogFacility(); 325 }
