在路上...

The development of life
我们一直都在努力,有您的支持,将走得更远...

站内搜索: Google

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

2009年8月26日

摘要: 在 Linux 下面大多通过命令行方式工作,如果能将 bash 提供的编程结构和各命令结合 起来,写成功能强大的脚本,将会节省很多时间,显著的提高效率。下面就介绍 bash 提供 的语法结构,步入我们的 shell 编程之路。 阅读全文
posted @ 2009-08-26 23:56 palam 阅读(284) 评论(0) 推荐(0)

摘要: feh 一个基于命令行的高速图片查看器,非常实用:sudo apt-get install fehWhen viewing a slideshow, the following keys may be used:---------------------------------------------------------------------------------------p Goto ... 阅读全文
posted @ 2009-08-26 23:56 palam 阅读(1022) 评论(0) 推荐(0)

摘要: Ubuntu 方便宜用,最值得让人称道的便是其安装软件的方式, 一条命令: sudo apt-get install xxx 就几乎能帮你搞定所有的软件安装难题。但是有时你可能有这样的需求,查看某个软件包是否安装、安装在哪 阅读全文
posted @ 2009-08-26 23:55 palam 阅读(472) 评论(0) 推荐(0)

摘要: 1. 制作 iso 镜像文件 dd if=/media/cdrom of=movie.iso bs=10242. 挂接/御载 iso 文件 sudo mount -o loop -t iso9660 movie.iso /media/cdrom sudo umount /media/cdrom3. 用 Mplayer 播放 dvd/vcd mplayer dvd://1 -dvd-device /... 阅读全文
posted @ 2009-08-26 23:54 palam 阅读(417) 评论(0) 推荐(0)

摘要: 什么是远程过程调用 RPC(Remote Procedure Call)? 你可能对这个概念有点陌生, 而你可能非常熟悉 NFS, 是的, NFS 就是基于 RPC 的. 阅读全文
posted @ 2009-08-26 23:54 palam 阅读(409) 评论(0) 推荐(0)

摘要: 偶像 Steve Vinoski 在 maillist 的回帖中一不留神就泄漏了他为 ErlangeXchange 准备的 session ,我们可以先一睹为快。Steve 大拿是 CORBA 界的牛人,对 RPC 是 bad 很有发言权地。这篇文章也写得很漂亮,水分相当少,我就不干“损失味道”的事情了。 为方便阅读,将 mail 内容盗版如下: Well, if you ... 阅读全文
posted @ 2009-08-26 23:53 palam 阅读(378) 评论(0) 推荐(0)

摘要: 本示例为 Client/Server 结构,通过代码演示 Client 如何建立连接,并向远程端发送数据;Server 端如何侦听系统连接请求,接收请求并建立连接,进而获取客户端发来的数据。代码虽短,却描述了整个通信过程 阅读全文
posted @ 2009-08-26 23:50 palam 阅读(475) 评论(0) 推荐(0)

摘要: 文件和缓冲区操作C-x C-f打开文件C-x C-c退出 emacsC-x C-v读入另一个文件,替换掉当前缓冲区中的文件C-z挂起 emacsC-x i打开文件并插入到当前光标位置C-x C-r只读方式找开文件C-x C-w文件另存为C-x C-s保存文件查找和替换C-s增量查找C-r反向开始增量查找C-M-s正则表达式增量查找C-M-r反向正则表达式增量查找C-s RET查找(非增量)C-r ... 阅读全文
posted @ 2009-08-26 23:48 palam 阅读(250) 评论(0) 推荐(0)

摘要: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; w3m mode;;;;;(add-to-list 'load-path (concat path-prefix "w3m"))(setq w3m-icon-directory (concat path-prefix "w3m/icons"))(requi... 阅读全文
posted @ 2009-08-26 23:47 palam 阅读(1235) 评论(0) 推荐(0)

摘要: 前些日子在 skyeye 上 porting 了 arm-linux,于是迫不及待的写了一个 module 试试,可很不幸,没有成功。小弟最近才搞 linux 的 module 技术,很多地方不是很懂,现将问题贴出,希望大家不吝赐教。skyeye(version 1.2.4) 的配置文件 skyeye.conf:===========================================... 阅读全文
posted @ 2009-08-26 23:44 palam 阅读(444) 评论(0) 推荐(0)

摘要: 本文旨在将 arm-linux 在 skyeye 上搭建起来,并在 arm-linux 上能成功 mount NFS 为目标, 最终我们能在 arm-linux 里运行我们自己的应用程序. 其实在 skyeye 上移 植 arm-linux 并非难事,网上也有不少资料, 只是大都遗漏细节, 以致细微之处卡壳,所以本 文力求详实清析, 希望能对大家有点用处。 阅读全文
posted @ 2009-08-26 23:43 palam 阅读(568) 评论(0) 推荐(0)

摘要: MicroEMACS 3.8 Help screens M- means to use the <ESC> key prior to using another key^A means to use the control key at the same time as the A key^V or [Pg Dn] Scroll down M-< or <HOME> ... 阅读全文
posted @ 2009-08-26 23:41 palam 阅读(300) 评论(0) 推荐(0)

摘要: 读赵烔博士的 Linux 0.11 内核完全注释, 受益良多,总想在 Linux 0.11 搭建一个开发环境,这样可以按自己的想法修改内核代码并编译了。抱着这个想法,今天在 VMWare 上实践了一回。现将操作过程记录于下,一来做个备忘,二来若对有此想法的人稍有帮助,则甚欣慰矣!1. 获取 gcclib-1.40.taz2. 通过 VMWare 创建一个软盘映像文件 fd.flp3. 在 VMWa... 阅读全文
posted @ 2009-08-26 23:40 palam 阅读(757) 评论(0) 推荐(0)

摘要: 根文件系的组成:目录、Shell、库、脚本 阅读全文
posted @ 2009-08-26 23:38 palam 阅读(656) 评论(0) 推荐(0)

摘要: 以前用 C++ 做过的 DRM 项目,现抽取出其中核心的代码, 演示一下如何借助 DRM 对流媒体文件进行保护。虽然微软的 DRM 技术被破解了, 但那是以用户通过认证并下载证书为前提的。由是观之, 运用 DRM 对流媒体文件施以保护仍有一定意义,这毕竟比什么都不做要强嘛!/* drm.h*/#ifndef __DRM_H__#define __DRM_H__#include <string... 阅读全文
posted @ 2009-08-26 23:37 palam 阅读(641) 评论(0) 推荐(0)

摘要: 有时为了高效,有时为了直接控制硬件,有些模块我们不得不直接用汇编语言来编写,并且对外提供调用的接口,隐藏细节,这其实就是内联汇编。如何使用内联汇编?我们就以 GCC 为例,一窥其中奥秘 阅读全文
posted @ 2009-08-26 23:35 palam 阅读(367) 评论(0) 推荐(0)

摘要: 如何启用 MMU, 并实现虚拟地址到物理地址映射正是这次实验的目的。呵呵,你也许已经迫不及待... 那现在我们就去探个究竟! 阅读全文
posted @ 2009-08-26 23:30 palam 阅读(932) 评论(0) 推荐(0)

摘要: 1 ARM GNU 汇编伪指令简介 (1)abort .abort 停止汇编 (2)align .align absexpr1,absexpr2 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或 32. 第二个表达式值表示填充的值 (3)if...else...endif .if .else .endif: 支持条件预编译 (4)include .include ... 阅读全文
posted @ 2009-08-26 23:25 palam 阅读(597) 评论(0) 推荐(0)

摘要: FS2410 (核心板为三星 s3c2410)开发板上实现了中断,包括响应时钟 Timer0, 响应按键,并实现了串口通信,能把任何数据通过 UART0 发送到 PC 机上的超级终端上进行显示,这样也便于调试。前两天又实现了 MMU 的启用代码,欢呼雀跃啊..., 可就在这个时候问题来了... MMU 启用后中断不能响应了!, start.S 的代码片段如下(arm-linux-gcc 汇编格式)... 阅读全文
posted @ 2009-08-26 23:24 palam 阅读(508) 评论(0) 推荐(0)

摘要: 中断服务程序在操作系统中无疑占有非常重要的地位,编写中断程序不仅要会运用底层的 汇编语言,还要了解 ARM 的体系架构。那这一节我们就通过中断编程来响应 FS2410开发板 上的 16 个按键,实现依次按下16个键时,D9~D12 四个 Led 从 0~15 进行计数,并通 过上个实验实现的 uart_printf 向串口发送数据 Kn is pressed!。 阅读全文
posted @ 2009-08-26 23:22 palam 阅读(589) 评论(0) 推荐(0)

摘要: 到目前为止我们所编写的程序都是直接烧到裸板(FS2410)上运行,没有借助操作系统, 如果哪个环节出错了,就只能揣测代码的逻辑,无法借助 GDB 调试,这无形增加了编写代 码的难度,如果任意时刻我们能把某个变量的值打印出来多好啊...呵呵, 你也许有同样的 困惑,上一个实验我们对 UART 串口编程实现了对超级终端接收和发送数据,也许我们可以 编写一个类似 C 语言里的 printf,作用就是向上位机的超级终端发送我们指定的任何数据。 怀着这样美好的愿望,随我一起踏上征程吧。 阅读全文
posted @ 2009-08-26 23:18 palam 阅读(573) 评论(0) 推荐(0)

摘要: 串口通信我们并不陌生,我们经常用串口来进行数据传输,可并不清楚它是如何工作 的。那这一节我们就来揭开 ARM S3c2410 UART(Universal Asynchronous Receiver and Transmitter) 串口通信的神秘面纱 阅读全文
posted @ 2009-08-26 23:16 palam 阅读(559) 评论(0) 推荐(0)

摘要: I. Programmer's Model 1. ARM instruction set Branch instructions Data-processing instructions Status register transfer instructions Load and store instructions Coprocessor instructions Exception-gener... 阅读全文
posted @ 2009-08-26 23:14 palam 阅读(483) 评论(0) 推荐(0)

摘要: 通过将 Nand Flash 前 4K 代码搬移到 SDRAM 中,了解如何初始化并使用 ARM 的内存,为编写 ARM bootloader 和搬移内核到内存作准备。 阅读全文
posted @ 2009-08-26 23:13 palam 阅读(442) 评论(0) 推荐(0)

摘要: 通过将 Nand Flash 前 4K 代码搬移到 SDRAM 中,了解如何初始化并使用 ARM 的内存,为编写 ARM bootloader 和搬移内核到内存作准备。 阅读全文
posted @ 2009-08-26 23:08 palam 阅读(515) 评论(0) 推荐(0)

摘要: 1. 为 root 设置密码 sudo passwd root 提示输入密码,第一次要输入当前帐户的密码,之后输入新密码,再输入新密码的确认 密码, root 的密码就会设置成功。2. 切换到 root 下进行作业 su root3. 设置网络代理,使 apt-get 能安装软件 (1)在/etc/apt目录下新建文件 apt.conf (2)编辑 apt.conf 内容如下 Aquire::ht... 阅读全文
posted @ 2009-08-26 23:03 palam 阅读(321) 评论(0) 推荐(0)

摘要: 通过实现FS2410板子上的D9、D10、D11、D12四个发光二极管的循环点亮,了解ARM嵌入式开发的基本流程。 阅读全文
posted @ 2009-08-26 23:00 palam 阅读(525) 评论(0) 推荐(0)

摘要: // 头文件 Calc.h#ifndef __CALC_H__#define __CALC_H__ #include <stack>#define ascii_int(x) (x >= 0x30 && x <= 0x39) ? (x - 0x30) : (x)const int GREATER = 1;const int EQUAL = 0;const in... 阅读全文
posted @ 2009-08-26 22:57 palam 阅读(1088) 评论(0) 推荐(0)

摘要: 使用grep搜索文件内容——快捷、方便 阅读全文
posted @ 2009-08-26 22:54 palam 阅读(366) 评论(0) 推荐(0)

摘要: 预处理器(Preprocessor)   1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)      #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL  我在这想看到几件事情:   1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)   2)懂得预处理器将为你计算常数表达式的值,因此,... 阅读全文
posted @ 2009-08-26 21:55 palam 阅读(236) 评论(0) 推荐(0)

摘要: C++的拷贝函数和赋值函数既有联系又有区别,不细究的话很容易搞混,遂以小例示之如下,权作解惑之用 阅读全文
posted @ 2009-08-26 21:53 palam 阅读(520) 评论(0) 推荐(0)

摘要: 1. 当程序出错并产生core 时快速定位出错函数的办法 gdb 程序名 core文件名(一般是core,也可能是core.xxxx) 2. 调试程序使用的键rrun运行.程序还没有运行前使用c cuntinue运行到下一断点处qquit 退出tabtab命令补全功能hhelp帮助sstep 跟入函数nnext 执行下一行的代码。如果是函数调用,也当作一行代码,执行到此函数返回bbreakpoi... 阅读全文
posted @ 2009-08-26 21:51 palam 阅读(1196) 评论(0) 推荐(0)

摘要: # 下面的变量可以在shell 的环境变量里面指定。 # 也可以象下面这样在 Makefile 里面指定。 # CC=gcc # 编译器 # CFLAGS=-Wall -Werror -g # 编译器参数 # LD=gcc # 连接器参数 # LDFLAGS= $(LIBS) -lpthread # 连接器参数 # DEPENDFLAG=-MM # 生成依赖关系文件的参数 # INCLUDES=-Idir1 -Idir2 # 指明包含外部头文件的目录 # LIBS=-la -lb -lc # 指明引用外部的库文件 阅读全文
posted @ 2009-08-26 21:51 palam 阅读(352) 评论(0) 推荐(0)

摘要: 函数库文件也就是对Object文件(程序编译的中间文件)的打包文件。在Unix下,一般是由命令"ar"来完成打包工作。 阅读全文
posted @ 2009-08-26 21:49 palam 阅读(359) 评论(0) 推荐(0)

摘要: 在我们使用Makefile时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标文件(Unix下是[.o]文件,Windows下是[.obj]文件)。本章讲述的就是一些在Makefile中的“隐含的”,早先约定了的,不需要我们再写出来的规则。 “隐含规则”也就是一种惯例,make会按照这种“惯例”心照不喧地来运行,那怕我们的Makefile中没有书写这样的规则。例如,把[.c]文件编译成[.o]文件这一规则,你根本就不用写出来,make会自动推导出这种规则,并生成我们需要的[.o]文件。 “隐含规则”会使用一些我们系统变量,我们可以改变这些系统变量的值来定制隐含规则的运行时的参数。如系统变量“CFLAGS”可以控制编译时的编译器参数。 阅读全文
posted @ 2009-08-26 21:45 palam 阅读(426) 评论(0) 推荐(0)

摘要: 一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的。但也有时你也许只想让make重编译某些文件,而不是整个工程,而又有的时候你有几套编译规则,你想在不同的时候使用不同的编译规则,等等。本章节就是讲述如何使用make命令的。 阅读全文
posted @ 2009-08-26 21:43 palam 阅读(365) 评论(0) 推荐(0)

摘要: 在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能。make所支持的函数也不算很多,不过已经足够我们的操作了。函数调用后,函数的返回值可以当做变量来使用。 阅读全文
posted @ 2009-08-26 21:38 palam 阅读(270) 评论(0) 推荐(0)

摘要: 使用条件判断,可以让make根据运行时的不同情况选择不同的执行分支。条件表达式可以是比较变量的值,或是比较变量和常量的值。 阅读全文
posted @ 2009-08-26 21:36 palam 阅读(695) 评论(0) 推荐(0)

摘要: 在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。其与C/C++所不同的是,你可以在Makefile中改变其值。在Makefile中,变量可以使用在“目标”,“依赖目标”,“命令”或是Makefile的其它部分中。 变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空字符(空格、回车等)。变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。传统的Makefile的变量名是全大写的命名方式,但我推荐使用大小写搭配的变量名,如:MakeFlags。这样可以避免和系统的变量冲突,而发生意外的事情。 阅读全文
posted @ 2009-08-26 21:35 palam 阅读(1072) 评论(0) 推荐(0)

摘要: 每条规则中的命令和操作系统Shell的命令行是一致的。make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非,命令是紧跟在依赖规则后面的分号后的。在命令行之间中的空格或是空行会被忽略,但是如果该空格或空行是以Tab键开头的,那么make会认为其是一个空命令。 我们在UNIX下可能会使用不同的Shell,但是make的命令默认是被“/bin/sh”——UNIX的标准Shell解释执行的。除非你特别指定一个其它的Shell。Makefile中,“#”是注释符,很像C/C++中的“//”,其后的本行字符都被注释。 阅读全文
posted @ 2009-08-26 21:33 palam 阅读(433) 评论(0) 推荐(0)

摘要: 规则包含两个部分,一个是依赖关系,一个是生成目标的方法。 在Makefile中,规则的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么。一般来说,定义在Makefile中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。如果第一条规则中的目标有很多个,那么,第一个目标会成为最终的目标。mak... 阅读全文
posted @ 2009-08-26 21:32 palam 阅读(413) 评论(0) 推荐(0)

摘要: make 命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。 首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是: 1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。 2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。 3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。 只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。 阅读全文
posted @ 2009-08-26 21:30 palam 阅读(215) 评论(0) 推荐(0)

摘要: 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。 阅读全文
posted @ 2009-08-26 21:28 palam 阅读(236) 评论(0) 推荐(0)

摘要: 过程如下所示:/* shrobj.c 文件 */const char *myfunc(){ return "Hello World";} /* hello.c 文件 */#include <stdio.h>extern const char *myfunc();main(){ printf("%s\n", myfunc()); return 0;}编译: gcc -fpic -c sh... 阅读全文
posted @ 2009-08-26 21:21 palam 阅读(206) 评论(0) 推荐(0)

摘要: 如何在C++中调用已经被编译好的C函数?下面的小例子展示了这个过程:1. 假设某C函数如下定义/* file foo.c*/#include <stdio.h>int add(int x, int y){ return x + y;}编译并生成DLL:gcc -fpic –c foo.cgcc –shared -o foo.dll foo.o2. 在C++中调用... 阅读全文
posted @ 2009-08-26 21:18 palam 阅读(402) 评论(0) 推荐(0)

摘要: Starting EmacsTo enter Emacs , just type its name: emacsTo read in a file to edit, see Files below. Leaving EmacsSuspend Emacs C-zExit Emacs C-x C-cFilesRead a file into EmacsC-x C-fSave a file back t... 阅读全文
posted @ 2009-08-26 21:14 palam 阅读(394) 评论(0) 推荐(0)

摘要: `C-' Control-(即 Ctrl-),按住 Ctrl 键再按其他键 `M-' Meta-(或 Alt-),按住 Alt 键再按其他键;或按一下 ESC,再按其他键 `C-M-' Control-Alt-,按住 Ctrl 和 Alt 两个键再按其他键 point 位点。文档中的一个位置,一般是光标的左下角 mark 标记。由命令设置,用来定义/保存文档中的位置信息 region 区域。在 mark 和 point 之间部分,称为一个 region RET 回车键 TAB 制表符键 ESC ESC 键 SPC 空格键 Backspace, 退格键 Delete 删除键 阅读全文
posted @ 2009-08-26 21:12 palam 阅读(201) 评论(0) 推荐(0)

摘要: gcc/g++在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件[预处理器cpp] 2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs] 3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as] 4.连接目标代码,生成可执行程序[链接器ld] 阅读全文
posted @ 2009-08-26 21:07 palam 阅读(412) 评论(0) 推荐(0)

摘要: D. XPath例程代码#include <libxml/parser.h> #include <libxml/xpath.h> xmlDocPtr getdoc (char *docname) { xmlDocPtr doc; doc = xmlParseFile(docname); if (doc == NULL ) { fprintf(stderr,"Docu... 阅读全文
posted @ 2009-08-26 21:02 palam 阅读(660) 评论(0) 推荐(0)

摘要: 写属性类似于给一个新元素写文本。在这个例子中,我们将添加一个reference结点URI属性到我们的文档中。完整代码:附录F,添加属性例程代码。 reference是story元素的一个子结点,所以找到并插入新元素及其属性是简单的。一旦我们在parseDoc进行了错误检查,我们将在正确的位置加放我们的新元素。但进行之前我们需要定义一个此前我们不见过的数据类型。 阅读全文
posted @ 2009-08-26 21:01 palam 阅读(631) 评论(0) 推荐(0)

摘要: Libxml 是一个实现读、创建及操纵XML数据功能的C语言库。这个指南提供例子代码并给出它基本功能的解释。在这个项目的主页上有Libxml及更多关于它可用的资料。包含有完整的API文档。这个指南并不能替代这些完整的文档,但是阐明功能需要使用库来完成基本操作。 阅读全文
posted @ 2009-08-26 21:00 palam 阅读(1092) 评论(0) 推荐(1)

摘要: GNU binutils是一组二进制工具集。包括:addr2line ar gprof nm objcopy objdump ranlib size strings strip. 本文归纳他们的常用法。 阅读全文
posted @ 2009-08-26 20:59 palam 阅读(468) 评论(0) 推荐(0)

摘要: 编程设计 设计流程 C++ 的设计原则 对象关系 重用设计 设计易于使用的接口 设计通用的接口 协调一般性和通用性 代码注释 编写代码 精通类和对象 C++ 中的继承机制 覆盖方法的特殊情况 利用模板编写通用代码 C++ 中的一些疑难问题 C++ 中的 I/O 操作 C++ 中的异常 阅读全文
posted @ 2009-08-26 20:51 palam 阅读(307) 评论(0) 推荐(0)

摘要: Boost内容广泛,数值计算、泛型编程、元编程、平台API……不妨从容选择自己感兴趣的部分,细细品味。 Boost是什么?一套开放源代码、高度可移植的C++库。 谁发起的?C++标准委员会库工作组。 阅读全文
posted @ 2009-08-26 20:45 palam 阅读(367) 评论(0) 推荐(0)