text:
Oberon/ETH Oberon/Tutorial/GadgetsOberon

Using Gadgets from within Oberon

[ Text | Contents | Index | Master index]

Objective
You have most probably read the tutorial Using Gadgets to learn how to create user interfaces interactively and to learn how to define simple behaviors for these interfaces. Having mastered this first and simplest step in using the Oberon System 3, we invite you to tackle the next and slightly more demanding step, namely that of placing the behavior of the user interface under program control. This entails writing fairly simple procedures in Oberon. To illustrate how to achieve that, code fragments of at most 20 lines are presented and explained in great details. You should regard these fragments as sound theoretical building elements susceptible of integration in workable procedures that you might fancy to develop. To help you to reach your goal even better and faster, all fragments have been implemented in the modules Examples.Mod which will be used throughout this tutorial for live demonstrations.

Estimated time: 60 minutes.

How to prepare your environment
Click on the "Log" icon in your desktop to open an "Oberon.Log". Move that viewer to the top right corner of your desktop and remember to keep an eye on the Log viewer whilst doing the exercises. Now move this tutorial viewer to the top left corner of the desktop and make sure there is some free space in your desktop. You will use that free space later on as playground. If the playground becomes crowded, you may take the initiative to remove superfluous visual gadgets. Exercises are not at all confined to those suggested in the tutorial, you would do well to apply the exercises to other objects found on your desktop. You are now invited to print the source text "Examples.Mod" on paper for consultation, with for example Edit.Print LPT1 Examples.Mod ~ on your local printer.

How to control gadgets with commands
An important feature of the Oberon system is the capability to invoke commands from ordinary text. The Gadgets module exports a number of commands with which you can directly interrogate or change gadgets. These commands are described in the Gadgets module and in Attributes. Several gadgets, such as a button, have a Cmd attribute, which may contain a command. This command is executed when the gadget is activated (e.g. when a button is clicked). This device enables you to delegate the control of a gadget to yet another gadget.

The following panel demonstrates such a situation. On the right you have a color picker and on the left a rectangle named "Color", i.e. "Color" is the value of its Name attribute. The color picker's Cmd attribute has the value:
 * Gadgets.Set Color.Color #Col ~.

Now, press the middle mouse key when on the color picker, position the arrow pointer on a color of your choice and release the key. The color of the rectangle is changed. In this case one of the commands exported by the Gadgets module is used, but you are not limited to these.

If the construction of new commands is a declared objective of this tutorial and of yourself, one programming problem is that of supplying the commands with information about the environment in which they are executed.

Where to obtain information on the environment
The Gadgets module exports four variables Gadgets.context, Gadgets.executorObj, Gadgets.senderObj and Gadgets.receiverObj supplying the commands with the necessary information on the environment or context.

Gadgets.context
This global variable is set when a gadget executes a command and contains the context or parent of the gadget executing the command. This value may then be used to retrieve gadgets (visual or model gadgets) in that context. Setting this value under program control changes the context.

Example: the procedure Gadgets.FindObj(context, name) may be used to look for a named gadget in a given context.

Gadgets.executorObj
This global variable is set when a gadget executes a command and contains the gadget executing the command. This value is also stored in the global variable Oberon.Par.obj.

Gadgets.senderObj
This variable only contains a valid value when a consume operation (drag and drop) is executed. It then contains the gadget being either consumed (e.g. a picture gadget consumed by a button) or dropped onto another gadget (e.g. a button onto a panel).

Gadgets.receiverObj
This variable only contains a valid value when a consume operation (drag and drop) is executed. It then contains the gadget consuming another gadget (e.g. a button consuming a caption).

Alternative environment information sources
The Oberon module exports the variables Oberon.Par.obj and Oberon.Par.frame supplying similar environment information to commands. Also the Objects module supplies an information.

Oberon.Par.obj
This global variable is set when a gadget executes a command and contains the same value as Gadgets.executorObj.

Oberon.Par.frame
This global variable is set when a gadget executes a command and contains (a pointer to) the outermost frame in which the command is executed, i.e. that of the desktop.

Objects.NewObj
This global variable is set when a new object is created with either the procedure CreateObject or the procedure CreateViewModel. It then contains the new object. This variable allows other commands or procedures to process the new object, the simplest process being the insertion of the new gadget at the caret position in the display space.

How to control gadgets with messages
The frame messages in the Display module derived from Display.FrameMsg play a central role in inter-frame communication. These build a communication protocol allowing frames to communicate with each other without knowing too much about each other. The latter is crucial if foreign or yet unknown objects are to be integrated into the system and applications need to exchange objects with each other. The FrameMsg is defined as follows:

DEFINITION Display; (* excerpt only! *) FrameMsg = RECORD (Objects.ObjMsg) F: Frame; (* target frame *) x, y, res: INTEGER END END Display.

F plays a central role in the FrameMsg. It determines the destination or target frame of a message. Often the destination frame of a message is unknown. This happens for example when model update messages are broadcast. In this case the F field is set to NIL.

Caution: It is very important to initialize the message fields correctly. The res field common to all messages, is used to store a result value (>= 0). M.res therefore always should be initialized to -1.

Accessing gadgets - Display.SelectMsg
A client module can interrogate and control the display space by broadcasting a SelectMsg to the display space or to a given frame. A list of visual gadgets can be addressed on condition that they all have the same ancestor.

DEFINITION Display; (* excerpt only! *) CONST get = 0; set = 1; reset = 2; TYPE SelectMsg = RECORD (FrameMsg) id: INTEGER; time: LONGINT; sel: Frame; obj: Objects.Object END END Display.

where: - id is the message identifier determining which action to perform on a gadget. The following actions are defined:
 * get: When interrogating which gadget or gadgets are selected in the display space, the destination of the message is unknown. Therefore the field F must be set to NIL. On return the fields obj and sel are set.
 * set: Select the visual gadget specified in the destination frame field F.
 * reset: Deselect the visual gadget specified in the destination frame field F.

When id=set or id=reset the visual gadget is NOT redrawn. The client module must request a redraw by broadcasting a DisplayMsg.

- time contains, on return, the time of the selection when id=get. This field is unaltered if no object is selected. It is therefore important to initialize it with a negative value (time:=-1). - sel contains, on return, the ancestor of the selected object(s) when id=get. - obj contains, on return, the selected object (or the first object of a list) when id=get.

(*-- Access a list of selected gadget(s) one by one. --*) PROCEDURE EnumSelection; VAR S: Display.SelectMsg; obj: Objects.Object; BEGIN S.id := Display.get; S.F := NIL; S.time := -1; Display.Broadcast(S); IF (S.time > 0) & (S.obj # NIL) THEN obj := S.obj;               (* Access the first object *) WHILE obj # NIL DO      (*-- Process this object --*) obj := obj.slink       (* Access the next object *) END END END EnumSelection;

Exercise: 1) Select any number of gadgets in your display space and interrogate them with Examples.GetSelection (uses id=get). 2) Deselect all gadgets and repeat the question.

(*-- Select a gadget --*) PROCEDURE SelectGadget*; VAR S: Display.SelectMsg; obj: Objects.Object; BEGIN obj := Gadgets.FindObj(Gadgets.context, "Test"); IF (obj # NIL) THEN S.id := Display.set; S.F := obj(Display.Frame); S.obj := NIL; S.sel := NIL; Display.Broadcast(S); (* Use the information collected *) Info(S.obj); Info(S.sel); (* Redraw the gadget *) ...  END END SelectGadget;

Exercise: 1) Click the left button in this panel, to execute the command Examples.SelectGadget (uses id=set): 2) Display the information on that gadget named "Test" which has just been selected Examples.GetSelection (uses id=get). 3) Deselect that gadget again with Examples.DeselectGadget (uses id=reset). If you attempted to deselect the button 'Test' with a right mouse key click, it would fail: the panel is locked!

Removing gadgets - Display.ControlMsg
A client module can control the display space by broadcasting a ControlMsg to a given frame, specified in the destination frame field F of the base FrameMsg. A list of visual gadgets may be addressed on condition that they all have the same ancestor. DEFINITION Display; (* excerpt only! *) CONST remove = 0; suspend = 1; restore = 2; TYPE ControlMsg = RECORD (FrameMsg) id: INTEGER END END Display.

where: - id is the message identifier which determines which action to perform in the display space. The following actions are defined:
 * remove: Remove the destination frame(s) from the display space. Only the frame is (or the frames are) removed from the display space. The object(s) still exist(s) and may be restored to the display space at the caret location using Gadgets.Integrate(obj) for example.
 * This is either to delete it or to insert it into a new parent.
 * suspend: Temporarily remove a frame from the destination downwards from the display space.
 * restore: Restore a frame from the destination downwards to the display space. Frames which may have missed messages while suspended will then update their internal data structures.

Model program for removing a gadget from the display space: PROCEDURE RemoveGadget(obj: Objects.Object); VAR C: Display.ControlMsg; BEGIN C.id := Display.remove; C.F := obj(Gadgets.Frame); C.res := -1; Display.Broadcast(C) END RemoveGadget;

Exercise:

1) Place the caret in a free area of your desktop (outside of this viewer!). 2) Insert a panel gadget at that point with Gadgets.Insert Panels.NewPanel. 3) Select that gadget. 4) Remove it with Examples.RemoveSelection (uses id=remove). 5) Again place the caret in a free area of your desktop. 6) Re-insert the gadget at the caret with Examples.RestoreRemoved.

Resizing / Moving a gadget - Display.ModifyMsg
A client module can resize or move a visual gadget in the display space by broadcasting a ModifyMsg to a given frame, specified in the destination frame field F of the base FrameMsg. DEFINITION Display; (* excerpt only! *) CONST reduce = 0; extend = 1; move = 2; display = 0; state = 1; TYPE ModifyMsg = RECORD (FrameMsg) id: INTEGER; (* reduce, extend, move *) mode: INTEGER; (* display, state *) dX, dY, dW, dH: INTEGER; X, Y, W, H: INTEGER END END Display. where: - id is the message identifier which determines which action to perform in the display space. The following actions are defined:
 * reduce or extend: Resize frame to the specified Width and Height.
 * move: Move the frame to the new coordinates X and Y.

- mode is set to state, the frame should not display itself immediately but only update its coordinates or size. This message must never be invalidated and the dX, dY, dW, dH change coordinates should always be set. (*-- Resize a gadget to (W, H) --*) PROCEDURE ResizeTo(F: Gadgets.Frame; W, H: INTEGER); VAR M: Display.ModifyMsg; BEGIN M.id := Display.extend;   (* or M.id := Display.reduce *) M.mode := Display.display; M.F := F; M.X := F.X; M.Y := F.Y;       (* Same coordinates *) M.dX := 0; M.Y := 0; M.W := W; M.H := H;       (* New size *) M.dW := W-F.W; M.dH := H-F.H; Display.Broadcast(M) END ResizeTo; Exercise:

1) Place the caret in a free area of your desktop (outside of this viewer!). 2) Insert a panel gadget at that point with Gadgets.Insert Panels.NewPanel. 3) Select that gadget. 4) Determine the gadget coordinates and size with Examples.LocateGadget (uses SelectMsg). 5) Resize the gadget with Examples.Resize 120 45. The size values W=125 and H=45 are not editable in this viewer.

If you copy these two Example commands in an editable viewer, say Oberon.Log, you may exercise with other gadgets and sizes on your desktop. Adequate size values can be chosen using the values produced in step 4). (*-- Move a gadget to (X, Y) --*) PROCEDURE MoveToXY(F: Gadgets.Frame; X, Y: INTEGER);  VAR M: Display.ModifyMsg; BEGIN   M.id := Display.move;   M.mode := Display.display;   M.F := F;   M.X := X; M.Y := Y;        (* New coordinates *)   M.dX := X-F.X; M.dY := Y-F.Y;   M.W := F.W; M.H := F.H;    (* Same size *)   M.dW := 0; M.dH := 0;   Display.Broadcast(M) END MoveToXY; Exercise:

1) Place the caret in a free area of your desktop (outside of this viewer!). 2) Insert a panel at that point with Gadgets.Insert Panels.NewPanel. 3) Select that gadget. 4) Determine the gadget coordinates and size with Examples.LocateGadget (uses SelectMsg). 5) Copy this Examples.MoveGadget X Y command to an editable viewer, say Oberon.Log, and replace the X and Y by reasonable coordinates values infered from the data obtained in the previous step.

You may also exercise with other gadgets and coordinates values on your desktop.

Locating a frame - Display.LocateMsg
A client module can interrogate the display space by broadcasting a LocateMsg to the display space. DEFINITION Display; (* excerpt only! *) TYPE LocateMsg = RECORD (FrameMsg) loc: Frame; X, Y, u, v: INTEGER END END Display. where: - loc contains, on return, the frame containing the point at the absolute coordinates X, Y. If no frame is found it contains NIL. - X, Y are the absolute coordinates of the point where the display space is interrogated. - u, v contain, on return, the relative coordinates of that point in the frame (relative to the frame's top left corner). (*-- Locate gadget at screen coordinates X, Y --*) PROCEDURE Locate*; VAR L: Display.LocateMsg; X, Y: INTEGER; BEGIN ...    (* Set X and Y *) L.X := X; L.Y := Y; L.res := -1; L.F := NIL; L.loc := NIL; Display.Broadcast(L); (* Use the information collected *) Info(L.loc); Out.String("u="); Out.Int(L.u, 5); Out.String(" v="); Out.Int(L.v, 5); Out.Ln  ... END Locate; Exercise: 1) Move the mouse pointer and place the star-shaped pointer within the limits of a frame on your desktop. 2) Determine which gadget is located at that point with Examples.Locate and observe where the pointer is located relative to the top left corner of the frame. Explain. 3) Repeat this with other gadgets and also with the pointer placed in a free area of your desktop.

(Re)drawing a gadget - Display.DisplayMsg
A client module can request the redrawing of gadgets by broadcasting a DisplayMsg. DEFINITION Display; (* excerpt only! *) CONST frame = 0; area = 1; TYPE DisplayMsg = RECORD (FrameMsg) id: INTEGER; u, v, w, h: INTEGER END END Display.

where: - id is the message identifier which determines which action to perform in the display space. The following actions are defined:
 * frame: Redraw the destination frame.
 * area: Redraw the area defined by u, v, w, h inside the destination frame.

- u, v, w, h define the relative coordinates u, v of an area of width h and of height w inside the destination frame, when id=area. These coordinates are determined relatively to the top left corner of the frame. (*-- Select gadget --*) PROCEDURE SelectGadget*; VAR S: Display.SelectMsg; obj: Objects.Object; D: Display.DisplayMsg; BEGIN obj := Gadgets.FindObj(Gadgets.context, "Test"); IF (obj # NIL) THEN (* Select the gadget *) ...      (* Redraw the gadget *) D.id := Display.frame; D.F := obj(Display.Frame); Display.Broadcast(D); ...  END END SelectGadget;

Attribute management - Objects.AttrMsg
Each gadget has a set of attributes representing the state, configuration or behaviour of the gadget. An attribute is a (Name, Value) pair, where the value is of type boolean, integer, real, character or string. An attribute is used to store the name, the value, a command string, an editing characteristic or other information of a gadget. For instance an attribute named "Cmd" may contain an Oberon command (string) which is executed when the gadget is activated (clicking the middle mouse key).

In the gadget system of Oberon System 3 attribute management is strictly and exclusively handled by sending messages, that is gadget attributes are retrieved and changed individually or enumerated by sending a message of type AttrMsg (defined in the module Objects) directly to a gadget, by calling it's handler with:
 * obj.handle(obj, message)

Note that object attributes can also be visualized and edited using a universal editor name "Inspector". DEFINITION Objects; (* excerpt only! *) CONST enum = 0; get = 1; set = 2; Inval = 0; String = 2; Int = 3; Real = 4; LongReal = 5; Char = 6; Bool = 7; TYPE AttrMsg = RECORD (ObjMsg) id: INTEGER; Enum: PROCEDURE (name: ARRAY OF CHAR); name: Name; res, class: INTEGER; i: LONGINT;           x: REAL; y: LONGREAL;       c: CHAR; b: BOOLEAN;       s: ARRAY 64 OF CHAR END END Objects.

where: - id is the message identifier which determines which action to perform on the attribute. The following values are defined:
 * get: Retrieve the value of the attribute name.
 * set: Set the value of the attribute name.
 * enum: Enumerate all the attributes of an object. The procedure enum is called repeatedly, once for each attribute

- Enum is an enumerator procedure that must be supplied by the sender when id=enum.

- name is the name of the attribute. It must be specified when id=get or id=set.

- res reports about the result: < 0 message not handled, >= 0 message handled.

- class is the type of attribute. The predefined types are listed above: Inval, String, ...

- i, x, y, c, b, s: only just one of these fields is used to store the attribute value. The field used is the one matching the type specified by the class value. When id=get the attribute value is returned in one of the fields. When id=set the attribute value to assign must be stored in one of the fields before sending the message.

Retrieving an attribute
Use id=Objects.get to retrieve an attribute value of a given object. The result is stored in one of the i, x, y, c, b, s fields. (*-- Retrieve a named attribute of an object --*) PROCEDURE GetAttr(obj: Objects.Object; name: ARRAY OF CHAR); VAR A: Objects.AttrMsg; BEGIN A.id := Objects.get; COPY(name, A.name); A.res := -1; obj.handle(obj, A); IF A.res >= 0 THEN   (* Attribute exists *) IF A.class = Objects.String THEN       (* value A.s *) ELSIF A.class = Objects.Int THEN       (* value A.i *) ELSIF A.class = Objects.Real THEN   (* value A.x *) ELSIF A.class = Objects.LongReal THEN(* value A.y *) ELSIF A.class = Objects.Char THEN   (* value A.c *) ELSIF A.class = Objects.Bool THEN   (* value A.b *) ELSE (* unknown class *) END ELSE                       (* Attribute does not exist *) END END GetAttr;

Exercise: 1) Select this object 2) Display that object's attributes with Examples.ShowValue. 3) Move the slider and repeat the query.

Setting an attribute
Use id=Objects.set to set an attribute value. (*-- Store a LONGINT value in a named object --*) PROCEDURE SetAttr(obj: Objects.Object; name: ARRAY OF CHAR; i: LONGINT); VAR A: Objects.AttrMsg; BEGIN A.id := Objects.set; COPY(name, A.name); A.class := Objects.Int; A.i := i;  A.res := -1; obj.handle(obj, A) END SetAttr;

Enumerating the attributes
Use id=Objects.enum to retrieve all attribute values.

VAR tmp: Objects.Object; (*-- Retrieve a named attribute --*) PROCEDURE RetrObjAttr(name: ARRAY OF CHAR); VAR A: Objects.AttrMsg; BEGIN A.id := Objects.get; COPY(name, A.name); A.res := -1; tmp.handle(tmp, A); IF A.res >= 0 THEN   (* Attribute exists *) (* A.class as in GetAttr *) ELSE                       (* Attribute does not exist *) END END RetrObjAttr;

PROCEDURE EnumAttr*(obj: Objects.Object); VAR A: Objects.AttrMsg; BEGIN A.id := Objects.enum; A.Enum := RetrObjAttr; A.res := -1; tmp := obj; obj.handle(obj, A) END EnumAttrs;

How to control gadgets with procedures
Preliminary remark: The command procedures exported by the Gadgets module are explained in the Using Gadgets tutorial.The gadgets module exports a whole palette of procedures, only some of which are described and commented here. Among these, some are provided to simplify programming only, that is the same functionality can be obtained using by sending some of the messages described in the previous chapter. Notes scattered in the text will draw your attention on these cases.

Procedures which are of special interest for programmers of new gadgets are explained in the Programming new Gadgets tutorial.

Creating an object - CreateObject
Gadgets.CreateObject(newproc: ARRAY OF CHAR): Objects.Object returns a new object from a new procedure. The newly created object is stored in the global variable NewObj in the Objects module and it can be referenced by Objects.NewObj. Note that the new gadget instance, a visual gadget or a model gadget, exists only IN the system. You can let a visual gadget appear in the display space by calling the Gadgets.Integrate procedure described below.

See how this is implemented in the example below.

Inserting a gadget at the caret location - Integrate
Gadgets.Integrate(obj: Objects.Object) integrates (i.e. inserts) the object O in the display space at the caret position.

(*-- Create a slider gadget and insert it at the caret position --*) PROCEDURE InsertAtCaret*; VAR obj: Objects.Object; BEGIN ...       obj := Gadgets.CreateObject("BasicGadgets.NewSlider"); Gadgets.Integrate(obj) END InsertAtCaret;

Exercise: 1) Place the caret in a free area of your desktop (outside of this viewer!). 2) Insert a slider gadget at that point with Examples.InsertAtCaret.

Creating a view/model pair - CreateViewModel
Gadgets.CreateViewModel(viewnewproc, modelnewproc: ARRAY OF CHAR): Display.Frame creates a view/model gadget pair, i.e. a visual gadget associated to a model gadget, for example a text field and a string. The newly created visual gadget is stored in the global variable Objects.NewObj and the newly created model gadget can be referenced by Objects.NewObj(Gadgets.Frame).obj. (*-- Create a text field linked to an integer and insert it at the caret position --*) PROCEDURE InsertPair*; VAR F: Display.Frame; obj: Objects.Object; BEGIN F := Gadgets.CreateViewModel("TextFields.NewTextField", "BasicGadgets.NewInteger"); Gadgets.Integrate(F); (* Name the model "Volts" *) Gadgets.NameObj(F(Gadgets.Frame).obj, "Volts"); (*-- Create a slider named "Slider" and link it to the integer --*) obj := Gadgets.CreateObject("BasicGadgets.NewSlider"); Gadgets.Integrate(obj); Gadgets.NameObj(obj, "Slider"); obj(Gadgets.Frame).obj := F(Gadgets.Frame).obj END InsertPair;

Exercise: 1) Place the caret in a free area of your desktop (not in this viewer!). 2) Insert a slider gadget at that point with Examples.InsertPair.

Naming an object - NameObj
Gadgets.NameObj(obj: Objects.Object; name: ARRAY OF CHAR) changes the name of any object (Note: ANY object, i.e. needs not to be a gadget at all).

See how this is implemented in the example above.

Retrieving an object's name - GetObjName
Gadgets.GetObjName(obj: Objects.Object; VAR name: ARRAY OF CHAR) retrieves the name of any object (Note: ANY object, i.e. needs not to be a gadget at all). (*-- Display names assigned in previous example --*) PROCEDURE ShowNames*; VAR S: Display.SelectMsg; ObjName: ARRAY 64 OF CHAR; BEGIN .....  Out.String("Visual gadget name: "); Gadgets.GetObjName(S.obj, ObjName); Out.String(ObjName); Out.Ln; (*-- This visual gadget may have no model --*) Out.String("Model gadget name: "); Gadgets.GetObjName(S.obj(Gadgets.Frame).obj, ObjName); Out.String(ObjName); Out.Ln END ShowNames;

Exercise 1: 1) Select the slider created before. 2) Prove that the names assigned are correct with Examples.ShowNames. 3) Deselect the slider and select the text field. 4) Execute Examples.ShowNames again and explain the result.

Exercise 2: Repeat the exercise with other gadgets on your desktop (using Examples.Shownames) and note that some have no model gadget. Explain.

Retrieving a public object - FindPublicObj
Gadgets.FindPublicObj(name: ARRAY OF CHAR): Objects.Object searches for a public object, the name of which is specified as "L.O". Where L is the name of a public library (e.g. Icons.Lib, a PublicPanel, ...) and O the name of the object. If no object of the given name exists NIL is returned.

Retrieving an object - FindObj
Gadgets.FindObj(context: Objects.Object; name: ARRAY OF CHAR): Objects.Object searches for a named object in the specified context. If no object of the given name exists NIL is returned.

(* Find a named gadget in a specified context. *) PROCEDURE FindObj*; VAR obj: Objects.Object; BEGIN (* Note that if this command is executed from a gadget          the context is already set at execution time, before           reaching this point. *) obj := Gadgets.FindObj(Gadgets.context, "Test"); IF (obj # NIL) & (obj IS BasicGadgets.Button) THEN ...       END END FindObj;

Exercise: 1) Click the left button in this panel, to execute the command Examples.FindObj:
 * [[File:OberonGadgetsOberon3.png]]

2) Read the new information in Oberon.Log and explain.

Updating a gadget - Update
Gadgets.Update(obj: Objects.Object) if obj is a frame, a Display.DisplayMsg is broadcasted, else a Gadgets.UpdateMsg is broadcasted. This is needed if the data of a visual or model gadget is changed directly.

Retrieving a frame - ThisFrame
Gadgets.ThisFrame(X, Y: INTEGER; VAR F: Display.Frame; VAR u, v: INTEGER) retrieves the frame F located at the absolute coordinates X, Y in the display space. u, v contain the relative coordinates of that point in the frame. These coordinates are determined relatively to the top left corner of the frame. (*-- Locate gadget at screen coordinates X, Y --*) PROCEDURE LocateP*; VAR F: Display.Frame; X, Y: INTEGER; u, v: INTEGER; BEGIN ....  (* Set X and Y *) Gadgets.ThisFrame(X, Y, F, u, v); (* Use the information collected *) Info(F); Out.String("u="); Out.Int(u, 5); Out.String(" v="); Out.Int(v, 5); Out.Ln  .... END LocateP;

Exercise: 1) Move the mouse pointer and place the star-shaped pointer within the limits of a frame on your desktop. 2) Determine which gadget is located at that point with Examples.LocateP and observe where the pointer is located relative to the top left corner of the frame. Explain. 3) Repeat this with other gadgets and also with the pointer placed in a free area of your desktop.

Executing a command - Execute
Gadgets.Execute(cmd: ARRAY OF CHAR; executor, dlink, sender, receiver: Objects.Object) executes the command string cmd. Sender and receiver only have a value for consume operations. Dlink is copied to Gadgets.context; Oberon.Par.obj is set to the executor, and Oberon.Par.frame is set to the outermost frame in which the command is executed.

Executing a command - ExecuteAttr
Gadgets.ExecuteAttr(F: Frame; attr: ARRAY OF CHAR; dlink, sender, receiver: Objects.Object) searches for a certain attribute attr of F to be executed as command.

Changing a gadget value directly - SetValue
BasicGadgets.SetValue(obj: Objects.Object) changes the "Value" attribute of a gadget of a type defined in the BasicGadgets module, after a direct change of its "val" field. Visual gadgets are automatically updated. (*-- Look for an integer model gadget called "Test" in the current context and increment its val field. The model is visualized by a text field. --*) (*-- This command must be executed in a given context. --*) PROCEDURE Inc*; VAR obj: Objects.Object; BEGIN obj := Gadgets.FindObj(Gadgets.context, "Test"); IF (obj # NIL) & (obj IS BasicGadgets.Integer) THEN WITH obj: BasicGadgets.Integer DO      INC(obj.val); BasicGadgets.SetValue(obj) END END END Inc;

Exercise:

1) Click on the "Inc" button at the top right corner of the panel and watch the Counter text field (starts at 0) and the slider (starts at 50) changing value or position. The "Inc" button's "Cmd" field contains "Examples.Inc". Executing the command causes a direct increment of two gadget values and the two views are updated. No Objects.AttrMsg is required.

Comparison between commands and procedures
The Gadgets module provides a number of commands which may be executed by the user or by gadgets to control gadgets and the display space. The same actions may be performed under program control using procedures (middle column). Objects and gadgets attributes can also be retrieved or changed by sending messages, defined in the Objects module, directly to objects. The following table summarizes that:

How to control documents
You may write your own procedures and command procedures to control the presentation of new or existing documents. A number of standard procedures will help you in doing that.

Loading an existing document - Documents.Open
Documents.Open(name: ARRAY OF CHAR): Document loads a named document from disk and returns the document. If a file of that name is not found NIL is returned. Note that the external document is internalized but not presented in the display space. To present it to the user you must use the next procedure.

For an example see the statement (*1*) in the procedure below.

Presenting a document - Desktops.ShowDoc
Desktops.ShowDoc(D: Documents.Document) opens a document in the desktop or in a viewer depending on the context. PROCEDURE OpenDoc(name: ARRAY OF CHAR); VAR D: Documents.Document; BEGIN D := Documents.Open(name); (*1*) IF D # NIL THEN Desktops.ShowDoc(D)   (*2*) END END OpenDoc;

Exercise: 1) Start the tutorial named "Tutorial User's Guide", a Book document, with Examples.OpenDoc which loads the document "Tutorials.Book" (*1*) and presents it (*2*). 2) Close the tutorial.

Creating a new document
Included in this release you will find several document types. With each document type a so-called document New procedure is associated. Calling this procedure causes (a new instance of) a document of the associated type to be created. The name of the New procedure is also recorded in the document itself. In this manner, a filed document can be recreated later on.

The New procedures currently available are listed in a table appearing in a subsequent chapter.

The procedure "InsertDoc" below shows how a new text document is created (*1*) and how it is given a name (*1a*).

Reminder: the command Desktops.OpenDoc uses the same new procedures to create and present new documents in the display space.

Initializing a document - Documents.Init
Documents.Init(F: Document, main: Gadgets.Frame) initializes a document with a 'container' gadget. (*-- Insert a new text document in the display space --*) (*-- and give it a name, e.g. "MyDoc.Text". --*) PROCEDURE InsertDoc(name: ARRAY OF CHAR); VAR D: Documents.Document; obj: Objects.Object; BEGIN TextDocs.NewDoc;                                      (*1*) D := Objects.NewObj(Documents.Document); COPY(name, D.name);                                   (*1a*) obj := Gadgets.CreateObject("TextGadgets.New");       (*2*) Documents.Init(D, obj(Gadgets.Frame);                 (*3*)   Desktops.ShowDoc(D, FALSE) END InsertDoc;

Overview of commands and procedures
When executed by the user or by a gadget, Gadgets.Insert causes a new visual (container) gadget to be presented in the display space whereas Desktops.OpenDoc causes a document gadget to be presented. The New procedure selected determines the gadget type or document type respectively.

The same result can be obtained under program control using standard procedures. Refer to the InsertDoc procedure above to see the three steps (*1*), (*2*) and (*3*) required. The following table summarizes what is needed for each document type.

The third step is to initialize the document with the appropriate gadget (*3*).

The system is also delivered with a number of special purpose documents.

A final example
As a final example we have a panel which simply adds two real numbers. Entering a number in any of the three textfields will keep the equation correct.

Use the Columbus inspector to see the attributes of selected gadgets. Note that the text fields have real model gadgets linked to them and a command attribute set to "Examples.Add".

The program behind this panel is rather simple:

MODULE Examples; IMPORT Objects, Gadgets, BasicGadgets, Out; PROCEDURE Add*; VAR x, a, b: BasicGadgets.Real; PROCEDURE GetReal(name: ARRAY OF CHAR): BasicGadgets.Real; VAR obj: Objects.Object; BEGIN obj := Gadgets.FindObj(Gadgets.context, name); IF (obj # NIL) & (obj IS BasicGadgets.Real) THEN RETURN obj(BasicGadgets.Real) ELSE RETURN NIL END END GetReal; BEGIN (* 1. get the real gadgets *) x := GetReal("xx"); a := GetReal("aa"); b := GetReal("bb"); IF (x = NIL) OR (a = NIL) OR (b = NIL) THEN RETURN END; (* 2. solve the equation *) IF Gadgets.executorObj(Gadgets.Frame).obj # x THEN (* command executed from text field aa or bb *) x.val := b.val -a.val END; (* 3. notify clients of model x that x.val has changed *) BasicGadgets.SetValue(x) END Add END Examples.

The Examples.Add command can be divided into three parts: (1) Retrieve the objects: Gadgets.FindObj(context, name) is used to find a named gadget in a context. Because the command is executed from a gadget, the context (the panel containing the text fields) is stored in the variable Gadgets.context. (2) Solve the equation. (3) Notify clients of the changed object: In the case of real gadgets this can be done by calling BasicGadgets.SetValue(obj) (alternatively Gadgets.Update(obj) could have been used).

What's next?
If you had liked to develop your own gadgets learn all about it in Programming new Gadgets.

Index
[ B | D | G | N | O | P ]

B

BasicGadgets.SetValue

D

Desktops.ShowDoc Display.ControlMsg Display.DisplayMsg Display.LocateMsg Display.ModifyMsg Display.SelectMsg Documents.Init Documents.Open

G

Gadgets.context Gadgets.CreateObject Gadgets.CreateViewModel Gadgets.Execute Gadgets.ExecuteAttr Gadgets.executorObj Gadgets.FindObj Gadgets.FindPublicObj Gadgets.GetObjName Gadgets.Integrate Gadgets.NameObj Gadgets.receiverObj Gadgets.senderObj Gadgets.ThisFrame Gadgets.Update

N

New document

O

Oberon.Par.frame Oberon.Par.obj Objects.AttrMsg Objects.NewObj

P

Procedures Procedures

Revised, afi 03 Mar 1995 Installed on 30 05 1997


text:
User talk:Mervat (WMF)

Welcome!
Welcome to Wikibooks, Mervat (WMF)!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

Hi Mervat,

It it OK if you use Reading room/General for circulars, rather than Reading room?

It's the correct location for that sort of content, and also it gets automatically archived.

Cheers, -- Jules (Mrjulesd) 19:56, 31 January 2022 (UTC)

 * Yes, sure. Thanks for moving the older messages. Mervat (WMF) (discuss • contribs) 19:40, 28 February 2022 (UTC)

The contest on wiki commons
The deadline has reached,the contest is supposed to be over. Mirabelle heavens (discuss • contribs) 14:18, 5 April 2022 (UTC)

Voting closes soon on the revised Enforcement Guidelines for the Universal Code of Conduct

 * You can find this message translated into additional languages on Meta-wiki.
 *  metawiki:Special:MyLanguage/Universal Code of Conduct/Revised enforcement guidelines/Announcement/Voting 3 •

Hello all,

Voting closes on the revised Universal Code of Conduct Enforcement Guidelines at 23.59 UTC on January 31, 2023. Please visit the voter information page on Meta-wiki for voter eligibility information and details on how to vote. More information on the Enforcement Guidelines and the voting process is available in this previous message.

On behalf of the UCoC Project Team, Mervat (WMF) (talk) 10:26, 30 January 2023 (UTC)

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: User talk:Mervat (WMF)


text: Sailing/Printable version

title: Sailing/Printable version


text: River Fishing/Printable version

title: River Fishing/Printable version


text:
Bodybuilding and Weight Training/Recipes

The Wikimedia Cookbook contains a number of healthy recipes to use in conjunction with your training. The cookbook also offers a guide on a High Protein Diet.


text:
User talk:50.92.202.47

END THE TRUMAN SHOW/edTV RELATED SHOWS

title: User talk:50.92.202.47


text:
User talk:Caro de Segeda

Welcome
Welcome, Caro de Segeda!

If you have any questions, you can ask in the assistance reading room or possibly contact me personally. -Gifnk dlm 2020 From Middle English Wikipedia 📜📖💻 (talk) 07:29, 1 February 2022 (UTC)

Mini Language
Hi, I see you started work on Salu, Jon! in the Mini language. Thank you very much for your contributions! I’m just curious to know a bit about the mini language. At first I thought it was the language of some really remote place but it’s in Shelf:Constructed languages, so it can’t be. I did a bit searching and found this reddit post. Are they about the same language or different ones? Thanks in advance, -Gifnk dlm 2020 From Middle English Wikipedia 📜📖💻 (talk) 07:31, 1 February 2022 (UTC)

 * Yes, it is that language. You can find more information here Caro de Segeda (discuss • contribs) 07:50, 1 February 2022 (UTC)

 * Looks good. Good luck with the book. As a side note, you can ping users using . -Gifnk dlm 2020 From Middle English Wikipedia 📜📖💻  (talk) 08:40, 1 February 2022 (UTC)
 * Thank you. If you are interested, there are also texts you can read in that language here Caro de Segeda (discuss • contribs) 09:22, 1 February 2022 (UTC)

 * Thanks! I will look into this. -Gifnk dlm 2020 From Middle English Wikipedia 📜📖💻 (talk) 09:26, 1 February 2022 (UTC)

Btw, do you intend on putting all the chapters in one page like is now or will you move to subpages? -Gifnk dlm 2020 From Middle English Wikipedia 📜📖💻 (talk) 14:16, 1 February 2022 (UTC)

 * For now they will be in one page as the project will move quite slow. Caro de Segeda (discuss • contribs) 14:23, 1 February 2022 (UTC)

 * I see. Suit yourself. -Gifnk dlm 2020 From Middle English Wikipedia 📜📖💻 (talk) 15:56, 1 February 2022 (UTC)

Sona
Hi, I see you have started work on the book Sona and plan to write it “in English, French, Spanish, German, Portuguese, Catalan, Russian, Japanese and Polish”. Are you sure all of this belongs in English Wikibooks? I may be wrong but from my understanding it’s better to have English in English Wikibooks, Polish in Polish Wikibooks, etc. - 🇺🇦 Slava🇺🇦Ukraini 🇺🇦 Heroyam🇺🇦Slava🇺🇦(talk)🇺🇦 11:43, 30 April 2022 (UTC)

 * I just took it from this, so if that book can be here, I don't see any issue with the one I am creating. Caro de Segeda (discuss • contribs) 16:48, 30 April 2022 (UTC)

 * Ok. Just letting you know that I’m not against this book in any way I just wasn’t sure if it fits for English Wikibooks. If you are taking inspiration from that book then I don’t see an issue either. - 🇺🇦 Slava🇺🇦Ukraini 🇺🇦 Heroyam🇺🇦Slava🇺🇦(talk)🇺🇦 14:41, 1 May 2022 (UTC)
 * Thank you :) Caro de Segeda (discuss • contribs) 17:33, 1 May 2022 (UTC)

Languages
Hi, I’m curious to know in which languages are the books Bune Ğonatan! and Holo, Jonathan! written in? Also regarding the Mirad Wiki you opened, you might be interested in the Dormancy Policy. If it stays inactive for too long it might get deleted so make sure to at least do some edits from time to time. - 🇺🇦 Слава🇺🇦Україні 🇺🇦 Героям🇺🇦Слава🇺🇦 (talk)🇺🇦 09:48, 9 September 2022 (UTC)

 * Bune Ğonatan! is in Lingaust and Holo, Jonathan! is in Cristianés, two conlangs.
 * Thanks for the Mirad Wiki advice, I will see what I will do. Caro de Segeda (discuss • contribs) 09:49, 9 September 2022 (UTC)

title: User talk:Caro de Segeda


text:
Wikibooks:Requests for import/Archives/2021/November

Cracking of wireless networks
to under Hacking/Attack, for example Hacking/Attack/Wireless_networks because of how-to style Conan (discuss • contribs) 19:21, 1 November 2021 (UTC)
 * Done! --Mbrickn (discuss • contribs) 07:27, 19 November 2021 (UTC)


text:
Topics in Abstract Algebra/Linear algebra

The Moore-Penrose inverse
Inverse matrices play a key role in linear algebra, and particularly in computations. However, only square matrices can possibly be invertible. This leads us to introduce the Moore-Penrose inverse of a potentially non-square real- or complex-valued matrix, which satisfies some but not necessarily all of the properties of an inverse matrix.

We will see below that given a matrix $$A$$, there exists a unique matrix $$A^+$$ that satisfies all four of the Moore–Penrose conditions. They generalise the properties of the usual inverse.

Basic properties of the Hermitian conjugate
We assemble some basic properties of the conjugate transpose for later use. In the following lemmas, $$A$$ is a matrix with complex elements and n columns, $$B$$ is a matrix with complex elements and n rows.

Existence and uniqueness
We establish existence and uniqueness of the Moore-Penrose inverse for every matrix.

This leads us to the natural definition:

Basic properties
We have already seen above that the Moore-Penrose inverse generalises the classical inverse to potentially non-square matrices. We will now list some basic properties of its interaction with the Hermitian conjugate, leaving most of the proofs as exercises to the reader.

The following identities hold:
 * 1) A+ = A+ A+* A$$
 * 2) A+ = A$$ A+* A+
 * 3) A = A+* A$$ A
 * 4) A = A A$$ A+*
 * 5) A$$ = A$$ A A+
 * 6) A$$ = A+ A A$$

Proof of the first one: $$A^+ = A^+AA^+$$ and $$AA^+ = \left(AA^+\right)^*$$ imply that $$A^+ = A^+\left(A A^+\right)^* = A^+A^{+^*}A^*$$. □

The remaining identities are left as exercises.

Reduction to the Hermitian case
The results of this section show that the computation of the pseudoinverse is reducible to its construction in the Hermitian case. It suffices to show that the putative constructions satisfy the defining criteria.

Products
We now turn to calculating the Moore-Penrose inverse for a product of two matrices, $$C = AB.$$

Another important special case which approximates closely that of invertible matrices is when $$A$$ has full column rank and $$B$$ has full row rank.

We finally derive a formula for calculating the Moore-Penrose inverse of $$A A^*$$.

Projectors and subspaces
The defining feature of classical inverses is that $$A A^{-1} = A^{-1} A = I.$$ What can we say about $$A A^+$$ and $$A^+ A$$?

We can derive some properties easily from the more basic properties above:

We can conclude that $$P = AA^+$$ and $$Q = A^+ A$$ are orthogonal projections.

We finish our analysis by determining image and kernel of the mappings encoded by the Moore-Penrose inverse.

Applications
We present two applications of the Moore-Penrose inverse in solving linear systems of equations.

Least-squares minimization
Moore-Penrose inverses can be used for least-squares minimisation of a system of equations that might not necessarily have an exact solution.

Minimum-norm solution to a linear system
The proof above also shows that if the system $$Ax = b$$ is satisfiable i.e. has a solution, then necessarily $$z = A^+b$$ is a solution (not necessarily unique). We can say more:

An immediate consequence of this result is that $$z$$ is also the uniquely smallest solution to the least-squares minimization problem for all $$Ax = b$$, including when $$ A $$ is neither injective nor surjective. It can be shown that the least-squares approximation $$Az = y \approx b$$ is unique. Thus it is necessary and sufficient for all $$x$$ that solve the least-squares minimization to satisfy $$Ax = y = Az = AA^+b$$. This system always has a solution (not necessarily unique) as $$Az$$ lies in the column space of $$A$$. From the above result the smallest $$x$$ which solves this system is $$A^+(AA^+b) = A^+b = z$$.


text:
User talk:Felix QW

Welcome!
Welcome to Wikibooks, Felix QW!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

Thanks for your contributions -- Jules (Mrjulesd) 10:54, 1 February 2022 (UTC)

Message from 77.189.243.68
ABB* changed to AAB Hi, please review https://en.wikibooks.org/w/index.php?title=Topics_in_Abstract_Algebra/Linear_algebra&diff=4030275&oldid=4030270. In Lemma 3 ABB$$ changed to AAB$$, for no apparent reason.

Message from 77.189.243.68, see Edit_filter/False_positives. -- Jules (Mrjulesd) 00:28, 1 March 2022 (UTC)

 * Very good spot, thank you two! Felix QW (discuss • contribs) 18:20, 20 March 2022 (UTC)

title: User talk:Felix QW


text:
Flora of New York/algae

Order Charales
Charales are freshwater green algae in kingdom Plantae, division Charophyta, class Charophyceae.

title: Flora of New York/algae


text:
User:Gfecontent

Nassir Hussin

title: User:Gfecontent


text:
Cookbook:Chickpea Omelette

Chickpea omelette is a simple and quick breakfast dish. It is suitable for vegan and vegetarian diets, and is a great source of protein.

Ingredients

 * 1 cup chickpea flour
 * 1 teaspoon baking powder
 * Salt
 * 1 teaspoon ground turmeric
 * 1 teaspoon paprika
 * 1 cup soy milk or water
 * 1 tablespoon olive oil

Procedure

 * 1) In a bowl, mix the chickpea flour, baking powder, salt, turmeric, and paprika until combined.
 * 2) Gradually add in the soy milk, and mix until the batter is fully combined.
 * 3) Heat up a skillet on medium heat and add the olive oil. Spread the oil across the pan and let it heat up a little.
 * 4) Pour the batter into the skillet. Cook until bubbles form in the middle. Then, carefully flip using a spatula.
 * 5) Cook the other side for about 30 seconds.
 * 6) Serve.

Notes, tips, and variations

 * Experiment with adding ingredients into the batter such as chives, bell peppers, and onions.

title: Cookbook:Chickpea Omelette


text:
Cookbook:Citric Acid

Citric acid, also known as sour salt, is a powdered edible acid.

Characteristics
Like table salt, citric acid looks like small white crystals. It is very sour, but otherwise completely neutral tasting. It may also come as a solution in water.

Selection and storage
Citric acid keeps very well. Just keep it in a dry container, and it will last for years.

Use
Since it is a powder with a one-dimensional flavor, citric acid is frequently used as a precise flavoring, adding sourness to food without the need to add any liquid. For example, it is used in many sour candies, beverages, dressings, and more. It can also help slow browning in some fruits and separate milk curds to make some cheeses.

Substitution
In theory, lemon or lime juice could be used instead of citric acid—however, it will be imprecise in the amount of sourness it adds, and it will also add liquid to the dish.

title: Cookbook:Citric Acid


text:
User:Tuhin Sheikh123

The Subtle Art of Not Giving a F*ck: A Counterintuitive Approach to Living a Good For decades we've been told that positive thinking is the key to a happy, rich life. "F*ck positivity," Mark Manson says. "Let's be honest, shit is f*cked, and we have to live with it." In his wildly popular Internet blog, Manson doesn't sugarcoat or equivocate. He tells it like it is - a dose of raw, refreshing, honest truth that is In this generation-defining self-help guide, a superstar blogger cuts through the crap to show us how to stop trying to be positive all the time so that we can truly become better, happier people.

For decades we've been told that positive thinking is the key to a happy, rich life. "F*ck positivity," Mark Manson says. "Let's be honest, shit is f*cked, and we have to live with it." In his wildly popular Internet blog, Manson doesn't sugarcoat or equivocate. He tells it like it is - a dose of raw,

title: User:Tuhin Sheikh123


text:
Cookbook:Acorn

An acorn is the edible nut of the oak tree.

Characteristics
Acorns come in a variety of shapes an sizes, but they have a tough outer shell and a rough "cap" surrounding the nut meat. The meat is mild once processed, but it is full of tannins, bitter, and mildly toxic when raw. The acorns of different species of oak trees will vary in tannin content. Ilex/holm/holly oaks in Western Asia produce relatively sweet acorns. In North America, white oaks are common, and their acorns are milder than those of other endemic varieties like red oak.

Acorns can also vary in fat, protein, and carbohydrate content, all of which will affect the flavor and cooked product. Higher fat content makes for a "moister" acorn and acorn meal, while carbohydrate-rich acorns are drier and make a finer flour.

Selection
Acorns mature over the spring and summer and fall from their trees in the fall. They can be gathered from fall to early spring, but after the fall there is a risk of them molding and/or sprouting. Gather the acorns as soon as they fall, discarding any that have a small hole in the site from oak weevils.

Storage
Freezing is the best way to store acorns, both before and after processing. This keeps them fresh and prevents the oils in them from turning rancid.

Processing
Acorns require significant preparation before they can be consumed.

First drying
Shelling acorns is easier once they are dry. You do this in wide shallow pans or a dehydrator to prevent mold growth. Ensure good air circulation.

Shelling
Shelling can be done with a hammer/mallet or a specialized nutcracker. Rounder acorns should be placed on their flat top, while long acorns should be placed on their sides before hitting with a hammer. Place the acorn meats immediately in water if desired to prevent oxidation.

Leaching
The tannins in acorns can be leached using either a hot or cold method. Hot leaching is faster, but it cooks the starch in the nut, which will affect its binding properties later on.

For hot leaching, place the nuts in a large pot of water. Bring to a boil, then drain and discard the water. Repeat the boiling and draining with fresh water until the nuts are mild enough to eat.

For cold leaching, there are two primary methods. The first involves tying the nuts in a cloth and submerging in a well-cleaned toilet tank (not toilet bowl). Flushing the toilet causes fresh cold water to flow over the acorns, which leaches out the tannins. The second method requires grinding the nuts, transferring to a container, and covering with cold water. Store the container in the fridge, changing the water periodically, until the meal is no longer bitter. Drain and squeeze out all liquid.

Final drying
If present, rub the thin skin off the nuts. Dry the leached acorns, preferably in a dehydrator. If you want to preserve the starch, keep the temperature below 150°F.

Use
Acorns can be eaten whole like other nuts, and when ground can used like other nut meals. Acorn meal contributes fat and protein to baked goods, though it has no gluten. It can also be used to make a porridge, much like cornmeal. Acorn starch jelly is used in Korean cuisine.

title: Cookbook:Acorn


text:
Cookbook:Dulce de Leche

Dulce de leche, also known as milk jam, is a confection made with milk and sugar.

Production
Strictly speaking, dulce de leche requires only milk and sugar to be cooked together until thick and browned. This can be achieved from scratch by simmering sugar and milk together until thickened and brown. However, sweetened condensed milk can be baked or boiled as well in order to save time. Adding a little baking soda will help make the final product darker.

Technically, dulce de leche is not a caramel—rather than from caramelization of sugar, it gets its similar color and flavor from the Maillard reaction between the sugar and the protein in the milk.

Characteristics
Dulce de leche ranges from tan to brown, depending on how long it is cooked and whether an alkaline substance is added during cooking. It is thick, sweet, and sticky, with the rich flavor of cooked milk. Sometimes it has a slight grittiness to it as a byproduct of cooking, but it is overall smooth.

If made from goat milk, as it often is in Mexico, dulce de leche is called "cajeta".

Selection and storage
Canned dulce de leche will keep, unopened, at room temperature. Opened or fresh dulce de leche should be stored in the fridge, though its high sugar concentration will allow it to stay good for around a month.

Use
Dulce de leche is widespread in Latin America and growing in popularity in the United States. It is often used as a spread or filling, as in the sandwich cookies called alfajores, or a flavoring, as in ice creams and custards. When cooked even longer, dulce de leche can be turned into a fudgy confection.

title: Cookbook:Dulce de Leche


text:
Flora of New York/iTax-break2

/Templates
 * -style="background-color:#f0f0f0; font-size:11px; line-height:11px"
 * colspan=2|

title: Flora of New York/iTax-break2


text:
PostgreSQL/Index Hash

PostgreSQL uses two fundamental strategies to implement Hash indices. First, a hash function maps column values of any type and length to a hash value of a fixed size of 32 bit. Such hash values together with the TIDs of their originating rows are the basic bricks for the Hash index. Second, an elaborated algorithm ensures that the size of the index file grows smoothly (that is, in a small amount of pages at one point in time) when additional index entries occur. Hence, it's an extendible hash.

To save space, the hash index doesn't store the original column value but only the computed hash value. This has some implications. The sort order of the computed hash values haven't any relation to the sort order of the original values. Therefore this index type can support only the  operator, but none of the other comparison operators like   or. Additionally, there is the danger of duplicates. Two different column values can create the same hash value. This is unavoidable because there are many more possible column values (any length) than possible hash values (fixed size). Thus, after reading the row according to the found TID, it's necessary to re-evaluate the column value from the heap.

In most cases - especially for long column values - the size of a hash index is smaller than the size of a B-tree index. Also, the execution time of reading and writing commands is often shorter.

The central part of a hash index consists of so-called buckets. They are a double-linked list of pages, where bucket entries are stored. The first page of a bucket can be accessed very fast because of a correlation between its number and certain bits of the hash value.

Description
During the creation and maintaining of a Hash index, several steps are conducted:
 * The column value and the TID of its original row are read.
 * A hash functions computes a hash value out of the original column value. Its size is always 32 bit - independent of its data type and data length.
 * The combination of hash value and TID builds a bucket entry.
 * There are several buckets, where the bucket entries are stored. Certain bits of the hash value determine which bucket owns and receives the bucket entry.
 * Buckets consist of a primary bucket page plus optional overflow bucket pages. Within the bucket, pages are linked together via a double-linked list.
 * If the primary bucket page and all its overflow pages don't offer a free slot for the new bucket entry, a new overflow page is created.
 * The ratio of the number of existing buckets to all bucket entries is computed. Depending on this value and the chosen  of the index, new buckets are created on-demand.

The meta page contains statistical data about the index: number of buckets and bucket entries, an array of links to buckets (hashm_spares), and more.

The primary and overflow bucket pages contain pairs of hash values and TIDs that point to rows of the heap.

The bitmap pages contain an array of bits, which indicates that there may be unused overflow pages (after DELETE operations to the according rows). Those pages can be reused by other buckets.

title: PostgreSQL/Index Hash


text:
User:Suraseo

Sura's 12th Standard Mathematics Guide
Description

SURA’S 12th Maths guide was developed by docile and dexterous authors. The 12th Maths guide 2021-22 was devised according to the updated samacheer kalvi 12th book syllabus propagated by Tamil Nadu State Board Council. SURA’s samacheer kalvi 12th Maths guide  is a combined guide of both volume 1 and 2. Our Maths guide for class 12 encompasses all the requirement of the students to comprehend the text and the evaluation of the samacheer kalvi 12th books.

Exhaustive additional questions and answers in all chapters. Government question and answers are incorporated at the end of every lesson. Free Self Evaluation workbook with model and additional question papers was attached with SURA’s 12th Maths guide. Government model question paper, First Mid-Term Test, Quarterly Exam, Half Yearly Exam June Exam and March (Mar. 2020) questions are enclosed at appropriate sections in 12th Maths guide. Government Examination Question paper for common quarterly and Half-yearly along with supplementary examination September question paper with answers was subjected in the 12th Maths guide.

SURA’S free maths self –Evaluation workbook is the comprised material of 12th maths book back answers, additional  1,2,3 and 5 marks additional questions. Practical Sessions was added for student’s better knowledge. Model question paper for quarterly, half-yearly was included. Though the book is subjected to Samacheer kalvi pattern facile words has been used which can be understood by students. Summarized lessons to reduce the burden of the students. SURA’S 12th STD maths study material is compressed of both volumes in 12th maths book, reduces the burden of lessons and act as a student friendly guide. 12th maths book back answer are given according to the revised pattern.

Points

 * Unit wise mock test with answers
 * The compressed guide reduces the burden of lessons and act as a student friendly guide
 * Clearly explained definitions for every term
 * Free Self Evaluation workbook with model and additional question papers was attached with SURA’s 11th std maths guide
 * Facile words to understand
 * Model assessment question papers with answers for every term
 * Updated Samacheer Kalvi syllabus according to the guidance released by Tamil Nadu State Board Council
 * Summarized lessons to  reduce the burden of the students

title: User:Suraseo


text:
Rust for the Novice Programmer/If statements and booleans

If Statements and Booleans
One fundamental concept is that we might want to do something different depending on something. For example, we might want to cap a number at a certain threshold, say 10. Thus, if the number is higher than 10, we want to set it to 10. To express this, we use what are called if statements. an if statement uses what are called booleans. A boolean is a value of either true or false. In Rust it is shortened to 'bool' to make it quicker to type. For example: Here we are using == which checks whether the two things on the left and right of it are equal. If they are it becomes true, otherwise it becomes false. Since 5 is not equal to 6, is_six will be false. There are other things like ==, called 'operators' since they operate on inputs. The most common ones are == which compares if two things are the same, != which compares if two things are not the same, > which compares if the left thing is greater than the right thing, >= which compares if the left thing is greater than or equal to the right thing and the reverse for < and <=.

We use these in if statements by putting a boolean in and if the boolean is true, we will go inside the {} of the if statement, otherwise not. So here, since is_six is false, we won't go inside the if braces and the number printed out will be 5. If however, we changed it to: Then since the number is equal to 5, is_five is true and we go inside the braces, causing number to be equal to 9 at the end. This is quite verbose so normally the boolean value wouldn't be put into a variable and would go directly into the if statement as follows: This is quicker to write, more concise and easier to change later so is generally preferred.

Let's say we wanted to add 4 if the number was equal to 6, and subtract 4 if the number wasn't equal to 6. How would we do this? We could do a second if statement using the != not equals operator like this: This will work, but is quite long and awkward to read and change. Instead we use the else operator: Here, since number isn't equal to 6, we go to the else and subtract 4 so number is equal to 1.

We can also combine if and else to do different things: For example, let's say we wanted to add 4 if number was less than 7, subtract 4 if number was greater then 9 and add 1 otherwise. This would be awkward to do as separate if statements, since if the number was 6, it is less than 7 so we would add 4, making it 10, which means we would then subtract 4 from it since it is greater than 9. Therefore, using else statements to separate each section into its own block is convenient. We can do that behaviour as follows: And the number ends up as 9.

Let's go back to the example at the start of capping a number at 10. Now we can do that and we can express it as a function. Then we can use this in main as follows: This will print out 8 and 10 since the 8 is less than 10, we go to the else {} part of the if statement, so just return 8 from the function. While with 14, it is greater than 10 so we go to the if {} part of the if statement, so return 10.

A key point about all these programming things is that they are quite simple. Their power comes from using them together. From little things big things grow!

Next: Loops and iteration


text:
User talk:NguoiDungKhongDinhDanh

Welcome!
Welcome to Wikibooks, NguoiDungKhongDinhDanh!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

Thanks for your contributions -- Jules (Mrjulesd) 13:29, 2 February 2022 (UTC)

title: User talk:NguoiDungKhongDinhDanh


text:
Template:Falsepositive/sandbox

 * Username

 * Page you were editing

 * Description

 * Date and time

 * Comments

title: Template:Falsepositive/sandbox


text:
User talk:Renvoy

Welcome!
Welcome to Wikibooks, Renvoy!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

Thanks for your contributions -- Jules (Mrjulesd) 15:59, 2 February 2022 (UTC)

title: User talk:Renvoy


text: Skaneateles Conservation Area/Trail marking


text:
User talk:PProdonoff

Welcome
Welcome, PProdonoff!

If you have any questions, you can ask in the assistance reading room or possibly contact me personally. 𝟙𝟤𝟯𝟺𝐪𝑤𝒆𝓇𝟷𝟮𝟥𝟜𝓺𝔴𝕖𝖗𝟰 (𝗍𝗮𝘭𝙠) 18:41, 2 February 2022 (UTC)

title: User talk:PProdonoff


text: Wu Chinese/Printable version

title: Wu Chinese/Printable version


text: Phonetics/Printable version

title: Phonetics/Printable version


text: Phonology/Printable version

title: Phonology/Printable version


text: Guernsey French/Printable version

title: Guernsey French/Printable version


text: Government and Binding Theory/Printable version


text: CAT-Tools/Printable version

title: CAT-Tools/Printable version


text: Historical Linguistics/Printable version


text: Word formation/Printable version

title: Word formation/Printable version


text: Introduction to Grammar/Printable version


text: Introduction to Linguistics/Printable version


text: Language Acquisition/Printable version

title: Language Acquisition/Printable version


text:
User:Raspbie/Collections/HAskell Test

test

 * Haskell
 * Haskell/Getting set up
 * C Programming/Why learn C?

title: User:Raspbie/Collections/HAskell Test


text:
User talk:Maungle

Welcome, Maungle!

If you have any questions, you can ask in the assistance reading room or possibly contact me personally. —Justin ( koavf ) ❤T☮C☺M☯ 07:00, 3 February 2022 (UTC)

title: User talk:Maungle


text:
Rust for the Novice Programmer/Loops and Iteration

Loops and iteration
Let's say we wanted to go through all the numbers from 1 to 100 and print out all the ones which are divisible by 6. How would we do this? Well, we could write a function checking if a number is divisible by 6 so let's do that first. By separating out the things we need to do we can deal with the problem one step at a time, which makes it easier to reason about. So first let's write the shell of the function: We use the comment here to indicate we're going to fill out the inside of the function. This won't compile currently since the function must return a boolean value of either true or false and at the moment it returns nothing. How do we check if a number is divisible by six? A quick refresher, being divisible by 6 means if it is divided by 6, the result will be a whole number. However, the input type is i32 so dividing by 6 will always return a whole number since it is doing integer division. So how do we proceed? One way would be to constantly subtract 6 from the number until we get to a number less than 6. If that number is 0, it means the number is divisible by 6, if not then it is not. Then the question is how do we express the 'constantly' 'until' in that logic. The answer is the while loop. A while loop while continually run whatever is inside the {} braces as long as the boolean value(called the condition) is true. This is a direct translation of the steps earlier into code. Note that we could write it as 6 < number which is the same but by convention we normally put the variable on the left of conditions since it is more natural to read and understand. What we are doing here is finding the remainder of input. This is quite a common thing, so there is a built-in way to do this, using the percent sign %. So a % b gets the remainder of a divided by b. Therefore, it is much simpler to write the function as this: We can simplify this further since remainder == 0 is already a boolean value that corresponds to what we want to return, so we can do: This is much better. The morale of the remainder operator is if you're doing something quite common, there's probably a simple way to do it and the best way to find these ways is generally to search.

Back to the original thing, which was to go through all the numbers from 1 to 100 and print them if they're divisible by 6. Now we can do this using a while loop, we just have to set a number to 1, then keep going through the loop while the number is less than or equal to 100. This works, but there is a built in easy way to iterate through numbers. These are called for loops, and we would rewrite the above as following: This does the same result as the while loop above but is a little cleaner. The 1..101 is called a range and it ranges from 1 to 100. The reason it has to be 101 on the right side of the .. is that it is non inclusive, meaning it doesn't include the last number. The reason for this will be seen later. We can use an inclusive range with ..= so 1..=100 would yield the same result. The 'for number in' indicates a variable called number that stores the value as the for loop goes through the values in the range. A for loop can iterate through anything that is an 'iterator' which will be explained soon.

Next: Arrays and Vectors


text:
User:Nattechs

Akolade Nathaniel

title: User:Nattechs


text: Wikijunior:Countries A-Z/Sri Lanka

title: Wikijunior:Countries A-Z/Sri Lanka


text: Wikijunior:Countries A-Z/Sri Lanka/Image


text:
Free Knowledge Culture Calendar/March 18

Nous sommes non seulement consommateurs mais aussi créateurs. Out of a need for visibility for Africans as creators, Made in Nigeria was launched today in 2017 to showcase software tools of global relevance that are made by Nigerians. It quickly took off when it was announced on Twitter two days later and spawned a wave of similar lists for other African countries.

Talent and brains are a major export of Africa, and the technology sector and Open Source (web) development are booming, especially in Nigeria, the world’s fastest-growing Open Source contributer region in 2020. Yet locals struggle to be recognized as creators and not just seen as passive consumers or even victims, with perceptions of Africans shaped by stereotypes and systemic racism rooted in colonialism. People regularly have to clarify that Africa is a whole continent, not just a country. Although Free Software is all about community, there was actually little diversity.


text: Template:Reviewer topicon

title: Template:Reviewer topicon


text:
Template:Reviewer topicon/doc

This template is not blank, it adds a little icon in the top-right corner. See?

Usage
Place anywhere on your user page to indicate that you are a Reviewer on English Wikibooks.

title: Template:Reviewer topicon/doc


text:
Canadian Refugee Procedure/91-91.1 - Representation or Advice

IRPA Sections 91-91.1
Sections 91-91.1 of the Immigration and Refugee Protection Act read: Representation or Advice

Representation or advice for consideration 91 (1) Subject to this section, no person shall knowingly, directly or indirectly, represent or advise a person for consideration — or offer to do so — in connection with the submission of an expression of interest under subsection 10.1(3) or a proceeding or application under this Act.

Section 91 restricts who can represent or advise a person for consideration, there are separate rules for those providing services that are unremunerated
Section 91(1) of the Act provides no person shall represent or advise a person for consideration - or offer to do so - except as authorised by s. 91 of the Act. For the RPD rule governing Counsel who are representatives without fee, see: Canadian Refugee Procedure/RPD Rules 3-13 - Information and Documents to be Provided. If there are allegations or concerns that a representative, who is not a member of the specific regulated professions listed above, is being paid for their services before the IRB, this is governed by the IRB’s Policy for Handling Immigration and Refugee Board of Canada Complaints Regarding Unauthorized, Paid Representatives. See also: Canadian Refugee Procedure/RPD Rules 14-16 - Counsel of Record. Persons who may represent or advise (2) A person does not contravene subsection (1) if they are (a) a lawyer who is a member in good standing of a law society of a province or a notary who is a member in good standing of the Chambre des notaires du Québec; (b) any other member in good standing of a law society of a province or the Chambre des notaires du Québec, including a paralegal; or (c) a member in good standing of the College, as defined in section 2 of the College of Immigration and Citizenship Consultants Act.

Section 91(2) sets out the four groups who may represent persons before the IRB for consideration
The previous Immigration Act was interpreted to permit unregulated “other counsel” to represent persons before the IRB. An amendment to the IRPA in 2011 changed that, restricting such representation to above four categories of licensed persons: lawyers, notaries (in Quebec), immigration consultants and paralegals.

Section 91(2)(c) provides that a member of the College of Immigration and Citizenship Consultants must be "in good standing" to represent persons before the IRB for consideration
Section 91(2)(c) of the IRPA provides that a member of the College of Immigration and Citizenship Consultants must be "in good standing" to represent persons before the IRB for consideration. In accordance with College By-Law 2021-2, the term “in good standing” means that the consultant, among other things, has met the College's learning requirements and has not been suspended. By-laws of the College of Immigration and Citizenship Consultants also provide that, as of July 1, 2023, immigration consultants must obtain a Class L3 licence from the College in order to be permitted to represent persons before the Immigration and Refugee Board. The qualifications for a Class L3 licence are higher than the qualifications a Class L2 licence that is needed for general immigration work. As such, section 91 of the IRPA may be interpreted such that “in good standing” means that the College permits the immigration consultant to practice in the particular area and so that immigration consultants who lack the required L3 licence contravene section 91 of the IRPA if they represent or advise a person for consideration. See also: Canadian Refugee Procedure/RPD Rules 3-13 - Information and Documents to be Provided.

Section 91(3): Students-at-law
Students-at-law (3) A student-at-law does not contravene subsection (1) by offering or providing representation or advice to a person if the student-at-law is acting under the supervision of a person mentioned in paragraph (2)(a) who is representing or advising the person — or offering to do so — in connection with the submission of an expression of interest under subsection 10.1(3) or a proceeding or application under this Act.

Agreement or arrangement with Her Majesty (4) An entity, including a person acting on its behalf, that offers or provides services to assist persons in connection with the submission of an expression of interest under subsection 10.1(3) or an application under this Act, including for a permanent or temporary resident visa, travel documents or a work or study permit, does not contravene subsection (1) if it is acting in accordance with an agreement or arrangement between that entity and Her Majesty in right of Canada that authorizes it to provide those services.

(5) [Repealed, 2019, c. 29, s. 296] (5.1) [Repealed, 2019, c. 29, s. 296] (6) [Repealed, 2019, c. 29, s. 296] (7) [Repealed, 2019, c. 29, s. 296]

Québec Immigration Act (7.1) For greater certainty, the Québec Immigration Act, CQLR, c. I-0.2.1, applies to, among other persons, every person who, in Quebec, represents or advises a person for consideration — or offers to do so — in connection with a proceeding or application under this Act and is a member of the College, as defined in section 2 of the College of Immigration and Citizenship Consultants Act.

(8) [Repealed, 2019, c. 29, s. 296]

Penalties (9) Every person who contravenes subsection (1) commits an offence and is liable (a) on conviction on indictment, to a fine of not more than $200,000 or to imprisonment for a term of not more than two years, or to both; or (b) on summary conviction, to a fine of not more than $40,000 or to imprisonment for a term of not more than six months, or to both.

Meaning of proceeding (10) For greater certainty, in this section, proceeding does not include a proceeding before a superior court.

IRPA s. 91(10): A proceeding under this Act does not include a proceeding before a superior court, and as such an immigration consultant may not provide representation on judicial review
Section 91(2) provides that persons may represent or advise for consideration in connection with a proceeding or application under this Act if they are a member in good standing of the College of Immigration and Citizenship Consultants or the Chambre des notaires du Quebec. However, this provision of the Act does not include a proceeding before a superior court. Therefore, this provision does not authorise an Immigration Consultant or a Quebec notary to represent a client on a judicial review of an IRB decision. Regulations 91.1 (1) The regulations may (a) establish a system of administrative penalties and consequences — including of administrative monetary penalties — applicable to the violations designated in regulations made under paragraph (b) and set the amounts of those administrative monetary penalties; (b) designate as a violation the contravention — including a contravention committed outside Canada — of any specified provision of this Act or of the regulations by any person who, directly or indirectly, represents or advises a person for consideration — or offers to do so — in connection with the submission of an expression of interest under subsection 10.1(3) or a proceeding or application under this Act; (c) prohibit acts in relation to the activity of representing or advising — or offering to do so — described in paragraph (b); and (d) provide for the power to inspect — including the power to require documents to be provided by individuals and entities for inspection — for the purpose of verifying compliance with the provisions specified in regulations made under paragraph (b).

Right to request review (2) Any regulation made under paragraph (1)(a) must provide that a person referred to in any of subsections 91(2) to (4) who is the subject of a notice of violation has the right to request, from a person appointed under subsection (3), a review of the notice or of the penalty imposed.

Appointment — order (3) The Governor in Council may, by order, appoint one or more Canadian citizens or permanent residents to conduct reviews in respect of notices of violation issued, or penalties imposed, under a regulation made under paragraph (1)(a) and to perform any other function conferred on them by a regulation made under that paragraph.

Tenure (4) A person appointed by order under subsection (3) holds office during good behaviour for a term that the Governor in Council may specify, by order, but may be removed for cause by the Governor in Council at any time.


text:
User:Dexxor

I mainly edit the Chess Opening Theory book. I have pretty good technical knowledge about MediaWiki, including templates and Lua modules.

My nickname "Dexxor" has no special meaning. I chose it because it is pronounceable and was not taken by someone else. If you see a "Dexxor" outside of Wikimedia, that is not me.

title: User:Dexxor


text:
User talk:102.141.196.149

T. Gregtregretgtr (discuss • contribs) 22:55, 3 February 2022 (UTC)

title: User talk:102.141.196.149


text:
Minecraft resource gathering/Tables

These are some tables that you can use as a quick reference.

For more information on crops, visit the page for it!

title: Minecraft resource gathering/Tables


text:
Talk:Skaneateles Conservation Area/Trail marking

Trails A0 & A1
I updated the SCA trails on OpenStreetMap to correspond with our new map and trail numbers a little better, and one question it brought up is what is the trail number for the first trail to the right off A0 from the O’Loughlin lot (the one that Todd recently moved)? It’s not numbered on the new maps. I called it “A0-bypass” on OSM for now, but it really doesn’t seem like a bypass to me. --- Nonenmac (discuss • contribs) 02:01, 4 February 2022 (UTC)

 * Tom suggested: For the trail to the right of A0, we could make it an extension of A1. A0 and A1 would share the bridge and crossover each other.  We have 30 A1 markers, so if we use them sparingly, we could cover the whole A1.

 * I had considered that but wasn’t sure of our policy on trails sharing short sections and whether Matt already had plans for those sections. If we can mark it clearly, I think it would work. I’ll update OSM with those sections marked A1 and F2 and see how that looks.  --- Nonenmac (discuss • contribs) 19:22, 4 February 2022 (UTC)
 * I believe this was the original intention with this trail and it was marked as such crossing the bridge. Additional signage may be needed/ mini-kiosk where the trails split off from each other on the East side of the creek Mleveroni14 (discuss • contribs) 18:34, 9 February 2022 (UTC)

As mentioned by others, trail A0 has some very steep spots that are difficult even when they are not icy. These spots may become prone to erosion with continued use and should be re-routed if possible. --- Nonenmac (discuss • contribs) 21:10, 24 February 2022 (UTC)

Trails F1 and F2
Also, the first (sharp) turn to the right off F1 coming from the Federal Farm parking lot doesn’t have a number on the new maps. I made it F1 on OSM, but we can’t have a trail split in 2 directions like that of course. Any ideas? --- Nonenmac (discuss • contribs) 02:01, 4 February 2022 (UTC)

 * Tom suggested: The F1 question doesn’t really have a clean fix, but we could label it F2. So F2 would go from the pavilion to F8 while sharing a section with F1.   We only have 10 F2 markers but I don’t think we would need more than that.

 * For F2, Matt and I had discussed previously running a trail up from the pavilion through the white cedar plantation to the bench under the Scots pines, so I added that to OSM and made it F2, connecting the 2 sections that way. I normally keep that section mowed to access the tree plantings, so it’s not really a new trail.  We would just mark it as such and maintain it a little more consistently. --- Nonenmac (discuss • contribs) 19:25, 4 February 2022 (UTC)
 * This sounds like a good change and it would make access to the tree planting areas much easier Mleveroni14 (discuss • contribs) 18:36, 9 February 2022 (UTC)


text:
Kirby franchise strategy guide/Enemies/Shotzo

The Shotzo is an undefeatable enemy in the Kirby series of games that takes on the guise of a small cannon. Some Shotzos can only shot in one direction, whilst others can rotate, although they do this very slowly. Kirby cannot inhale or harm these enemies, although they do an exceedingly good job of harming him. In Kirby 64: The Crystal Shards, Shotzos were split into two variants: those mounted on the ground and those mounted on walls.


text: File:KirbySS Great Cave treasures.png

title: File:KirbySS Great Cave treasures.png


text:
Kirby franchise strategy guide/Enemies/Sir Kibble

Sir Kibble is a recurring enemy in the Kirby games. It looks like a helmet with hands, feet, and a cutter boomerang, and attacks by throwing the boomerang at Kirby. If swallowed, it grants Kirby the Cutter power. With the cutter power Kirby can throw the boomerang at differing distances. He can also aim it up or down to reach enemies above or below. Another popular way to use the cutter ability is to throw it forward, wait for it to come back, then jump over it so that it hits an enemy behind Kirby. Kirby can also perform a melee combo, ending with his Final Cutter move, which later appeared as his up special in Super Smash Bros. Sir Kibble appeared on most episodes of Kirby: Right Back at Ya! where he was voiced by Scott McNeil.


text:
Kirby franchise strategy guide/Enemies/Poppy Bros.

The Poppy Bros. are a pair of enemies who appear in the Kirby games, usually as a mini-boss or a boss. An older version of the Poppy Bros. is Poppy Sr. Poppies all wear blue caps and hop around, throwing bombs at Kirby. Kirby can suck up the bombs and spit them back out at the Poppies to cause damage to them. They generally also hop around the area, trying to damage Kirby by touching him. A Poppy can be swallowed by Kirby to obtain the Bomb copy ability, or in Kirby: Nightmare in Dream Land the Crash ability, with which he can destroy all the enemies on the screen excluding Gordos and Shotzos. It can turn Kirby flashing yellow, or on Kirby Air Ride it gives him a blue hat, and the ability to throw bombs at enemies. The Bomb ability can also be turned into a Poppy Bro in Kirby Super Star, who will then throw bombs at enemies to help Kirby.

The Poppy Bros. also own one of three pinball tables in Kirby's Pinball Land, where they are featured as bosses. When the battle starts, there is one. By hitting him several times, another Poppy Bro will appear. They throw bombs at Kirby and at the flippers to disable them temporarily. By repeatedly hitting them, Kirby can defeat them.


text:
Kirby franchise strategy guide/Enemies/Scarfy

Scarfy is a type of enemy in the Kirby games. They look like orange, floating balls with cute, smiling faces and pointy ears. If Kirby attempts to use his default inhalation abilities on one it will drop its cutsey facade, turn brown, and pursue Kirby with its sharp teeth. Occaisionally they will pursue Kirby whenever his back is turned as well.


text:
Kirby franchise strategy guide/Enemies/Poppy Bros. Jr.

Poppy Bros. Jr. is a type of enemy in the Kirby games. Poppy Bros. Jr. appear in three forms. One form is a walking enemy wearing a blue cap. If Kirby comes in contact with it, he is damaged. The second form has the Poppy Bros. Jr. more closely related to the Poppy Bros. Sr., equipped with bombs that are lobbed at Kirby. When this form is absorbed, Kirby gains the Bomb ability. The third form is somewhat related to Sir Kibble, for instead of bombs, they throw returning boomerangs. The third form is only found in Kirby Super Star and yields the Cutter ability when swallowed.


text:
Kirby franchise strategy guide/Bosses/Paint Roller

Paint Roller is a boss who appears in a few Kirby games. It first appeared in Kirby's Adventure as the boss of Ice Cream Island in his classic canvas stage. It guarded the second fragment of the Star Rod, as ordered by King Dedede.

After its initial appearance in Kirby's Adventure, Paint Roller later appeared in its Game Boy Advance remake, Kirby: Nightmare in Dream Land. Later, it appeared in Kirby: Canvas Curse as one of Drawcia's clones. In Kirby & The Amazing Mirror, the magician character Wiz fights in a style very similar to Paint Roller.

In the Games
Paint Roller typically appears as a boss character on a pair of roller skates with a paint brush or pencil, drawing an enemy on a canvas which will spring out and attack Kirby once the painting is complete. To defeat it, Kirby normally has to swallow the newly created enemy and shoot it back at Paint Roller. This strategy is then repeated several times. The enemies that Paint Roller draws range from Waddle Dee to Kracko-like creatures to baseballs that hurl themselves at Kirby.

In Paint Roller's level in Kirby: Canvas Curse, when you play on level 3, you may have to draw things which are references to other Nintendo games. Included cameos that you may draw are the Triforce from The Legend of Zelda series, the Super Smash Bros. logo, the word "HAL" (from HAL Laboratory, the producer of the Kirby series) and the HAL Laboratory logo.

In the Anime
Paint Roller also appears in the anime. It appears in the Kirby anime episode, "Royal AcaDededemy, aired in the USA as "Dedede's Monsterpiece".

He made his debut when he was delivered to King Dedede, who didn't care about fine art. He went to Dedede's newly-built art museum, where he went around messing with the paintings. He painted a picture of his customer, which came to life startling the real King. It attacked Kirby with a laser gun that Paint Roller also painted until Meta Knight saved him by burning it with a torch. After Kirby inhaled PR's paintbrush, he became Paint Kirby, and they dueled and dodged with their paintings, which can come to life, as well as their roller blades. Kirby eventually got the best of Paint Roller with a painted missile of his, which homed in on the monster and his painted bomb, causing a massive, messy paint explosion that took out the entire art museum and splattered paint all over Kirby in the process.