summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Fix PCPP 'define' case; Keep PCPP output file if 'debug' ; GlueGen uses PCPP ↵Sven Gothel2010-11-075-21/+47
| | | | | | | | | | | | | | | | | | | | | | | | in same thread via File. Fix PCPP 'define' case ------------------------ A recursive define like: #define LALA ((int)1) #define LILI LALA was streamed out of PCPP, even though such 'macro defines' like #define LILI ((int)1) are disabled due to the parsers inability to digg those. Added test on macro definition for replaced values. GlueGen uses PCPP in same thread via File ------------------------------------------ To ease debugging we call PCPP from the same thread and use normal temp files as i/o. Keep PCPP output file if 'debug' --------------------------------- Keep temp outfile if debug is enabled
* PCPP: Add '# <line> <file>' pass through ; Fix NB antlr.jar referenceSven Gothel2010-11-072-2/+12
|
* Gluegen/PCPP: Refined PCPP if-elif-else-endif ; Add 'dumpCPP' option to ↵Sven Gothel2010-11-074-78/+126
| | | | direct PCPP to dump the output to stderr as well
* Fix PCPP encapsualted if/if blocksSven Gothel2010-11-073-18/+109
|
* PCPP Test: Add ifndef testsSven Gothel2010-11-072-1/+24
|
* PCPP: Add file and linenumber in exceptionsSven Gothel2010-11-071-3/+4
|
* Tests: Enable all tests ; Remove 'test' target -> 'junit.run' ; Fix junit ↵Sven Gothel2010-11-072-42/+42
| | | | | | | | | | | | chained tests; Enable all tests - Remove 'test' target -> 'junit.run' - calls build.xml tests first, then - calls build-junit.xml tests - build.xml unit tests were disabled, enable them via junit.run
* Enable ant based single test scriptSven Gothel2010-11-071-2/+19
|
* Fix testSven Gothel2010-11-071-2/+3
|
* PCPP: Fix ifdef/ifndef, if, elif and endif correct ; Enhanced PCPP testsSven Gothel2010-11-073-24/+97
|
* com.sun -> com.jogampSven Gothel2010-11-0714-0/+0
|
* gluegen-rt-cdc.jar -> gluegen-rt.cdc.jar to comply with JOGL cdc naming ↵Sven Gothel2010-11-072-9/+9
| | | | convention
* Relocation: GlueGen GL Parts to JoglSven Gothel2010-11-061-3/+1
|
* Relocation: GlueGen GL Parts to JoglSven Gothel2010-11-063-981/+0
|
* Renamed com.sun.gluegen -> com.jogamp.gluegenSven Gothel2010-11-0677-156/+177
|
* RELOCATION: GlueGen OpenGL parts back to JoglSven Gothel2010-11-067-2563/+0
|
* Avoid NPESven Gothel2010-11-063-5/+15
|
* Fixed benchmarking bugs in primitive HashMap test.Elijah C. Menifee2010-11-062-20/+29
| | | | | | | | | | | | | | | | | | | | | | Both IntIntHashMapTest and LongIntHashMapTest failed to reset test start time. The time values for intmapGetTime,mapGetTime,intmapRemoveTime,and mapRemoveTime all used the start time value from mapPutTime. This caused the following to be always/guarenteed to be true: mapPutTime < intmapGetTime < mapGetTime < intmapRemoveTime < mapRemoveTime thus not actually testing the following asserts: assertTrue("'get' too slow", intmapGetTime <= mapGetTime); assertTrue("'remove' too slow", intmapRemoveTime <= mapRemoveTime); In addition the results of the test were being printed before the actual test ran. Changed code to reset time to System.nanoTime() prior to each for loop, and moved time calculation and result output to below the test for loop. I also improved the output of the test info, by including the warmup status on benchmark start.
* removed ancient GL4Java file (ConvertFromGL4Java).Michael Bien2010-11-061-91/+0
|
* Fix native type representation; Retain typedef declName in resulting Type ↵Sven Gothel2010-11-0620-104/+237
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | for variables; Misc Fix native type representation ---------------------------------- The following custom types were previously build-in: __int32, __int64 Adding the following native build-in types (necessary): ptrdiff_t, size_t These compiler/platform specific types shall not be typedef'ed via header files. Hence we provide proper typing for such, as the compiler would do. Adding the following native build-in types (convenience): int32_t, uint32_t, int64_t, uint64_t These are provided due to their lack of support on certain platforms, and probable source of bugs, when defined by the user. Retain typedef declName in resulting Type for variables. -------------------------------------------------------- Adding Clonable to all cgram Type derivations. Assume use case: typedef khronos_ssize_t GLsizeiptr typedef size_t khronos_ssize_t The previous code picked a one level depth type in the dictionary if exists. Hence it made khronos_ssize_t visible in the javadoc and native code. It is our believe that the generated native code, as well as the javadoc comments shall reflect the original GlueGen'ed API and it's types. Also, aliasing or reducing native types via GlueGen could result in plattorm dependencies and in worst cases, incompatible native types. This patch clones the 1 level depth Type (typedef), clones it and sets the declName, so it's visible to the GlueGen layers. Misc ------- GlueGen's debug flag is passed to HeaderParser, where it traces misc information.
* add 'base.compile' target to skip compiling unit tests for faster ↵Sven Gothel2010-11-061-1/+3
| | | | development cycles
* Adding 'containsSafe' .. allowing verification of hash codeSven Gothel2010-11-051-2/+18
|
* Sort compiler/linker configs and add __unix__ and DEBUG defines as ↵Sven Gothel2010-11-051-85/+126
| | | | appropriate for all.
* Updated list of OpenGL extension vendor suffixesSven Gothel2010-11-041-0/+6
|
* Fix PCPP 'elif' case; Adding PCPP #error/#warning; Adding debug mode.Sven Gothel2010-11-043-13/+72
| | | | | | | | | | | | | | | | | | Fix PCPP 'elif' case ---------------------- Use the evaluated expression after the 'elif' statement as well. This was always true for 'if'. Otherwise the file obviously won't get parsed correctly, ie it was always assuming 'true'. Adding PCPP #error/#warning ---------------------------- LOG all occurence of #error and #warning CPP directives Adding debug mode. ---------------------- Add '--debug' commandline flag and 'debug' property for ant task, which enables debug mode of PCPP.
* TestRecursiveLock01: Reduce threads/loop, otherwise slow machines will time outSven Gothel2010-11-022-14/+14
|
* RecursiveLock: TRACE_LOCK: StackTrace -> err.printlnSven Gothel2010-10-291-2/+4
|
* ArrayHashSet: List toList() -> ArrayList toArrayList()Sven Gothel2010-10-261-7/+11
|
* ArrayHashSet: Add 'getOrAdd(key)' identity method to conveniently get the ↵Sven Gothel2010-10-232-5/+41
| | | | identity or add it, if not exist yet
* New jogamp.common.util.ArrayHashSet, providing O(1) queries/add and identity ↵Sven Gothel2010-10-235-20/+608
| | | | operations
* Moved locking to: com.jogamp.common.util.locks ; Better abstraction ; Misc ↵Sven Gothel2010-10-149-66/+302
| | | | changes
* fix runtest.sh scriptsSven Gothel2010-10-091-7/+12
|
* Added TestRecursiveToolkitLock; junit.run: disable inner classes in batch runSven Gothel2010-10-092-1/+283
|
* RecursiveToolkitLock relocation to gluegen finishedSven Gothel2010-10-091-2/+3
|
* Fix RecursiveToolkitLock: Implement complete fair FIFO scheduler ↵Sven Gothel2010-10-091-30/+67
| | | | (wait-interrupt) using a LinkedList
* Fix: NativeWindow RecursiveToolkitLock, GLWindow lockSurface/unlockSurfaceSven Gothel2010-10-091-67/+101
| | | | | | | | | | | | Fix: NativeWindow RecursiveToolkitLock - Use notify(), instead of notifyAll(), so only one thread is being awakened for the single resource. Otherwise starvation and timeout happen, since the oldest thread might not get waken up (earlier than other threads) within timeout. - Inner class for all synchronized (flow/mem) fields for easier fine grained sync/lock. Fix: GLWindow lockSurface/unlockSurface - Enter locked surface block only if surface lock could be acquired
* RecursiveToolkitLock default TO 5sSven Gothel2010-10-091-1/+1
|
* NEWT: Fix Display/Window/Screen OO Identity, Reparenting and requestFocusSven Gothel2010-10-091-2/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | NativeWindow: Interface NativeWindow changes: - Remove 'throws' qualifier in lockSurface(), since it is not - Adding convenient 'one call' isSurfaceLockedByOtherThread() - Adding getSurfaceLockOwner() NEWT Window/GLWindow: - Unclutter Window/GLWindow relationship - save Window's indentity GLWindow's role is a GLAutoDrawable implementation aggregating (maybe even compositioning) a Window. The previous implementation just derived from the Window implementation, overwriting methods and fields - impossible to ensure sanity / completness. It was also not ensured that the added functionality of GLWindow (setVisible, destroy, ..) has been issued in case of handling the aggregated Window alone (window callbacks, ..). To solve this issue in a 1st attempt without changing the GLWindow API, Window is just an interface, being implemented by their specializations, hence sanity is intrinsic. GLWindow's added functionality is ensured by a Window.LifecycleHook interfaced implementation, registered at the aggregated Window. - Screen and Window are interfaces now (new files) - Display is an abstract class. - Their (abstract) implementations resides in impl/<BaseName>Impl - GLWindow implements Window as well - Remove Screen reference handled by setScreen(Screen) method. - Lock native parentWindow if used (createNative/reparenting) - Move lockSurface/unlockSurface from unchecked override pattern to an callback style using abstract methods lockSurfaceImpl/... - Sorting all methods to semantic sections, abstract, superinterface, .. - Reparenting: Handling different reparenting situations: - Unchanged - No change - Native Reparenting - Compatible Display/Screen, try native reparenting - Native (Re)Creation - Use destroy/create pattern - Native Creation Pending - Create later - setUndecorated() calls reconfigure Window now, ie tries to change the window actually - Don't issue 'requestFocus()' directly from the native implementation anymore, call it from the Java code. - Window/GLWindow/NewtFactory: Constructor simplification Avoid explosion of constructor overloading, ie removing the 'undecorated' variant, since this is redundant due to the 'setUndecorated(boolean)' method. - Fixed/added API documentation
* NEWT: Changed Lifecycle of Display/Screen (part 2)Sven Gothel2010-10-091-1/+1
| | | | | | | | | | | | | | | | | | | | | Window Reparenting (unification): On the fly Display/Screen creation resides in NewtFactory. Reparenting logic within Window. Handles all reparenting cases now: ACTION_NONE, ACTION_SOFT_REPARENTING, ACTION_NATIVE_REPARENTING, ACTION_NATIVE_CREATION - out.println -> err.println ++++ - Bumbed windows bat scripts to 1.6.0_21 and ant 1.8.1 - Debug: /RecursiveToolkitLock.java TO is 300s for now, while not finished. - +++ Needs more testing. Deadlocks: AWT/NEWT parenting.
* GLAutoDrawable: setAnimator/getAnimator/invoke/display changes; NEWT: Adding ↵Sven Gothel2010-10-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | native repaint; Fix reparent/fullscreen New: NEWT Native Repaint ========================= Support for native repaint, which shall call display() in case no animator is running. GLAutoDrawable invoke(GLRunnable) impl. handles case if invoked on animator thread, or no animator thread is running (issueing a display() call). The impl resides in GLDrawableHelper. The Animator un-/registers itself at the GLAutoDrawable via setAnimator. New: NEWT AWT/NEWT Parenting Focus Handling ============================================ Introducing Window.FocusRunnable, to be registered at the NEWT Window, which will be executed before the native focus claim. Window.FocusRunnable's run method returns a boolean, which determines whether the native implementation shall proceed claiming the native focus. This API focus hook is necessary to allow an optional underlying windowing toolkit, ie AWT (see usage NewtCanvasAWT), to make the focus traversal transparent. Fix: GLEventListener / GLDrawableHelper ======================================== GLEventListener's init() and glViewport()/reshape() method must be called before the 1st display() and after a dispose() call. It could miss the 1st display() call if added after the setVisible(true) call - due to the native repainting. The impl resides in GLDrawableHelper. Fix: Misc NEWT ============== Window reparent issues a resize() and display() call, if it is visible. native Window uses direct send.*Event for input events (again), instead of enqueueing it for performance. Window impl all status change native event Java callbacks, instead of having duplicated code in all implementations. Fullscreen, reposition at zero. Reparent/Fullscreen repaint if visible. Native reparent/fullscreen, fix glitches on Windows (visibility while reparenting)
* GLAutoDrawable: setAnimator/getAnimator/invoke/display changes; NEWT: Adding ↵Sven Gothel2010-10-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | native repaint; NewtCanvasAWT focus fix Support for native repaint, which shall call display() in case no animator is running. GLAutoDrawable invoke(GLRunnable) impl. handles case if invoked on animator thread, or no animator thread is running (issueing a display() call). The impl resides in GLDrawableHelper. GLEventListener's init() and glViewport()/reshape() method must be called before the 1st display() and after a dispose() call. It could miss the 1st display() call if added after the setVisible(true) call - due to the native repainting. The impl resides in GLDrawableHelper. The Animator un-/registers itself at the GLAutoDrawable via setAnimator. NEWT Window reparent always issues a resize() and display() call. NEWT native Window uses direct send.*Event for input events (again), instead of enqueueing it for performance. NEWT Window implements all status change and Java native event callbacks, instead of having duplicated code in all implementations. NewtCanvasAWT if the Newt window is focused, the AWT/Swing component[s] will loose the focus.
* Fix: Locking/Threading; Common IntIntHashMap and Buffers; Fix: ↵Sven Gothel2010-10-091-6/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | glMap*Buffer*; GLX/WGL/CgGL: All runtime dynamic; Misc .. TODO: Compile and test on MacOSX .. Fix: ===== Multithreading/Locking: See jogl/doc/Implementation/MultiThreading.txt - Locking layer is not platform agnostic, ie GLContextImpl, GLDrawableImpl, .. and NEWT: Window/Display - No more use of JAWT global lock necessary, removed. - No need for X11 Display lock, on the contrary, this made the NV driver hang. - Use common window/surface lock - All NativeWindow surfaceLock's are recursive now glMapBuffer: If size is 0, don't do cont with the native call. glMapBufferRange: Fix capacity. glNamedBufferDataEXT: Track the size. glMapNamedBufferEXT: Manual impl. - use the tracked size glXGetVisualFromFBConfig, glXChooseFBConfig, glXChooseVisual: Instead of ignoring and implement a renamed version (*Copied), we just use ManualImplementation for the proper copy-result code. DesktopGLDynamicLookupHelper: Initialize _hasGLBinding* attributes in the determing loadGLJNILibrary() method, which is called by super(). Otherwise static init will overwrite them after the super() call. X11GLXDrawableFactory: Don't release anything at shutdown (removed sharedContext.destroy()), since this caused a freeze/SEGV sometimes. Fixed NEWT's reparentWindow() functionality incl NewtCanvasAWT usage. - Native: if not visible, don't focus, etc - NewtCanvasAWT: Use the container size to start with - Run the command on the EDT Using GlueGen's new DynamicLibraryBundle utility: - X11, Windows and MacOSX OpenGL adapted to DynamicLibraryBundleInfo. - X11GLXDynamicLookupHelper -> X11GLXDynamicLibraryBundleInfo - Remove all path from lib names. - GL order: libGL.so.1, libGL.so, GL - shallLinkGlobal: true -> to server some 'old' DRI systems -> http://dri.sourceforge.net/doc/DRIuserguide.html - shallLookupGlobal: false - Try both : glXGetProcAddressARB and glXGetProcAddress - Using bootstrap: GLX.glXGetProcAddress(long glxGetProcAddressHandle, String glFuncName) Found the issue with LIBGL_DRIVERS_PATH, ie if not set no valid GL instance can be found (ie ATI fglrx/DRI). This may happen if using a differen user than the desktop user for whom the env var is set within some /etc/X11/Xsession.d/ script. Enhancements: ============= GLBufferSizeTracker: Use IntIntHashMap and add DirectState size tracking. GLBufferStateTracker: Use IntIntHashMap. GLStateTracker: Use IntIntHashMap. GLDynamicLookupHelper: More generic (global loading/lookup and GetProcAddress function name list), remove redundant code. FIXME: MacOSXCGLDynamicLookupHelper: - Not tested - Not using NSImage lookup anymore as recommended by OSX API Doc, so dlsym is used always (to be tested) WindowsWGLDynamicLookupHelper: - Not tested GLX/WGL/CgGL is all runtime-dynamic as now, ie loaded and looked-up at runtime, no compile time dependencies to GL anymore, nor a need to specify CgGL. Split up WGL in GDI and WGL, to allow proper dynamic runtime linkage of OpenGL32 while using static binding to GDI32 NEWT events generated by native code are enqueued and not send directly. This should ease locking mechanisms .. if any are necessary. NEWT: More platform specific code moved to *Impl method, simplifying the generic code of the superclass and impl protocol. Cleanup: ========= Replace all InternalBufferUtil's with com.jogamp.common.nio.Buffers Removed all InternalBufferUtil's from repository Removed GLContextImpl notion of 'optimized' surface locking, where the surface gets unlocked during makeCurrent/release. This just makes no sense and would impact multithreading in a horrible way.
* NEWT: Fix AWT Parenting ; Multithreading Issues ; Semantics: destroy(), .. ; ↵Sven Gothel2010-10-091-7/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Misc. Due to incapabilities of the previous AWT/NEWT reparenting the implementation and spec had to be changed to support this feature. See the first 2 comments below. - Tested on GNU/Linux (OK), Windows (a few bugs left) - TODO: - Clarify the size/layout issue, ie who is responsible etc In the test, incl AWT/NEWT, we set the size on the GLWindow and ie pack the AWT Frame. - Fix remaining [Windows] bugs .. - Fix/Implement MacOSX port .. Fix AWT/NEWT reparenting: =========================== - Now NewtFactory's createWindow() method for parenting handles NativeWindow only and is no more responsible for creating a child window upon an AWT Component. See class com.jogamp.newt.awt.NewtCanvasAWT for NEWT/AWT parenting. - New com.jogamp.newt.awt.NewtCanvasAWT, responsible for handling AWT's reparent events via addNotify/removeNotify. Reparenting is implemented via the new NEWT Window's reparentWindow() method. Also sets the background erase to false, if supported. - Fix zero size semantics in Window (setSize/setVisible) Since a zero size window is not supported by many compoenent (Windowing system, OpenGL, ..) we use the visibility methodology to not show a 0x0 window. See Javadoc. AWT components may start with zero size. - New NEWT Window: reparentWindow(NativeWindow newParent, Screen newScreen) Allowing to change the parent of a window. Similar with the fullscreen toggle, but without size/position change. Native reparenting allows to keep alive the native window while changing the container, hence it is preferred to a destroy/create cycle. To benefit from the native reparenting, a NEWT implementation has to implement 'protected boolean reparentWindowImpl(long newWindowHandle)' and return true, otherwise reparenting will be 'emulated' via the expensive destroy/create cycle. - NEWT's Window references all of it's children, if any - NEWT's Window propagates setVisible/destroy actions to it's children. - Fix NEWT's destroy() semantics. A call of destroy() or destroy(false) shall only result in the destruction of the native window (handle) nothing more. A subsequent setVisible(true) shall allow the complete recreation of the Window into a usable state. A call of destroy(true) destroys all resources the Window holds, may include Screen/Display and OpenGL resources in case of GLWindow. This is necessary to allow proper reparenting, where a native window may become destroyed, but should be recreated via setVisible(true) later on. - Fix NEWT set[Size|Position|Fullscreen|Visible] synchronization. Use a recursive lock instead of the Window instance, otherwise arbitrary Window access via AWT's EDT, NEWT's EDT or other threads can block. Also removed a use pattern like: key.lock() try { EDT.invoke(action()); } finally { key.unlock(); } Where action() itself uses the same lock object (here key), the result is a deadlock. NativeWindow Changes: ====================== - We can use XInitThreads() now (concurrent threading support) in combination with AWT. Might have been some async in our NEWT locking in regards to AWT (sync()), and the X11 Display changes made in c787f50d77e2491eb0d8201d534a6fa4885a929e. - NativeWindow's window handle is _not_ transient like surface handle, fixed documentation. JOGL Changes: ============= - New 'isRealized()' method in GLDrawable. - Misc Fixes ============ - Fix NEWT set[Size|Position|Fullscreen|Visible] duplicate code Due to pure abstract signatures, the set[Size|Position|Fullscreen|Visible] implementations of X11, OSX, .. contained duplicate code and state handling (size, pos, ..). These are now decoupled, ie generic set[Size|Position|Fullscreen|Visible] implementations calling simple set[Size|Position|Fullscreen|Visible]Impl implementations. - Fix NEWT: Renamed setAutoDrawableClient(boolean) to setHandleDestroyNotify(boolean) The semantic of setAutoDrawableClient(boolean) defaults to false was too complicated and specific, hence changed to setHandleDestroyNotify(boolean) defaults to true since its more clear and the name refers the window itself.. - Fix NEWT: Removed GLWindow's unused global window list - Fix NEWT: Remove Window's unused event mask - Rename com.jogamp.newt.impl.awt.AWTNewtFactory -> com.jogamp.newt.awt.NewtFactoryAWT
* - Fix GLProcAddressResolver regression: Use GLProcAddressResolver !Sven Gothel2010-10-091-0/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | - X11GLXDrawableFactory: - Move shared resource creation/destruction into it's own thread - Remove the ATI hack (no XDisplay closing) for every Display, this is only necessary for the shared XDisplay and in case of AWT. - Newt - Display: Only pumpMessages if device is ready. - X11Display: Verify handle not null at DispatchMessage. - Common recursive ToolkitLock implementation, from src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java and src/newt/classes/com/jogamp/newt/Window.java, -> com.jogamp.nativewindow.impl.RecursiveToolkitLock - Unique XLockDisplay/XUnlockDisplay call via X11Util to simplify debugging. X11Util: Added debug code for XLockDisplay/XUnlockDisplay. Added fast LongObjectHashMap Added static lib loading and initialization. Removed active and passive list, as well as unused methods, to easy maintenance. Possible since the only 'uncloseable' Display might be the shareable one. - X11Lib: Added static initialization via X11Util Test: junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGears* - Add WindowListener for quit ..
* RunnableTask: Add attachmentSven Gothel2010-09-271-1/+18
|
* Fix my build scripts - thx 2 utgardaSven Gothel2010-09-242-2/+7
|
* Fix: In case of a sync notifyObject, the whole action must be ↵Sven Gothel2010-09-231-11/+34
| | | | synchronized/locked.
* LICENSE.txt changes:Sven Gothel2010-09-1429-457/+783
| | | | | | | | | | | | | - Added JogAmp Community and common denominator: New BSD 3-clause license - Added note to make/lib binary file (source and license) Added source and license text for external binaries used in build process (make/lib folder). Changed 'Sven Gothel' and 'Michael Bien' New BSD 3-clause license to 'JogAmp Community' Simplified BSD 2-clause license.
* LICENSE.txt changes:Sven Gothel2010-09-146-0/+711
| | | | | | | | | | | | | - Added JogAmp Community and common denominator: New BSD 3-clause license - Added note to make/lib binary file (source and license) Added source and license text for external binaries used in build process (make/lib folder). Changed 'Sven Gothel' and 'Michael Bien' New BSD 3-clause license to 'JogAmp Community' Simplified BSD 2-clause license.
* Simplify default value of product.build.numberSven Gothel2010-07-271-5/+1
|