亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? usbusx2y.c

?? linux-2.6.15.6
?? C
字號(hào):
/* * usbusy2y.c - ALSA USB US-428 Driver *2005-04-14 Karsten Wiese	Version 0.8.7.2:	Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom.	Tested ok with kernel 2.6.12-rc2.2004-12-14 Karsten Wiese	Version 0.8.7.1:	snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open.2004-12-02 Karsten Wiese	Version 0.8.7:	Use macro usb_maxpacket() for portability.2004-10-26 Karsten Wiese	Version 0.8.6:	wake_up() process waiting in usX2Y_urbs_start() on error.2004-10-21 Karsten Wiese	Version 0.8.5:	nrpacks is runtime or compiletime configurable now with tested values from 1 to 4.2004-10-03 Karsten Wiese	Version 0.8.2:	Avoid any possible racing while in prepare callback.2004-09-30 Karsten Wiese	Version 0.8.0:	Simplified things and made ohci work again.2004-09-20 Karsten Wiese	Version 0.7.3:	Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb().2004-07-13 Karsten Wiese	Version 0.7.1:	Don't sleep in START/STOP callbacks anymore.	us428 channels C/D not handled just for this version, sorry.2004-06-21 Karsten Wiese	Version 0.6.4:	Temporarely suspend midi input	to sanely call usb_set_interface() when setting format.2004-06-12 Karsten Wiese	Version 0.6.3:	Made it thus the following rule is enforced:	"All pcm substreams of one usX2Y have to operate at the same rate & format."2004-04-06 Karsten Wiese	Version 0.6.0:	Runs on 2.6.5 kernel without any "--with-debug=" things.	us224 reported running.2004-01-14 Karsten Wiese	Version 0.5.1:	Runs with 2.6.1 kernel.2003-12-30 Karsten Wiese	Version 0.4.1:	Fix 24Bit 4Channel capturing for the us428.2003-11-27 Karsten Wiese, Martin Langer	Version 0.4:	us122 support.	us224 could be tested by uncommenting the sections containing USB_ID_US2242003-11-03 Karsten Wiese	Version 0.3:	24Bit support. 	"arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works.2003-08-22 Karsten Wiese	Version 0.0.8:	Removed EZUSB Firmware. First Stage Firmwaredownload is now done by tascam-firmware downloader.	See:	http://usb-midi-fw.sourceforge.net/tascam-firmware.tar.gz2003-06-18 Karsten Wiese	Version 0.0.5:	changed to compile with kernel 2.4.21 and alsa 0.9.42002-10-16 Karsten Wiese	Version 0.0.4:	compiles again with alsa-current.	USB_ISO_ASAP not used anymore (most of the time), instead	urb->start_frame is calculated here now, some calls inside usb-driver don't need to happen anymore.	To get the best out of this:	Disable APM-support in the kernel as APM-BIOS calls (once each second) hard disable interrupt for many precious milliseconds.	This helped me much on my slowish PII 400 & PIII 500.	ACPI yet untested but might cause the same bad behaviour.	Use a kernel with lowlatency and preemptiv patches applied.	To autoload snd-usb-midi append a line 		post-install snd-usb-us428 modprobe snd-usb-midi	to /etc/modules.conf.	known problems:	sliders, knobs, lights not yet handled except MASTER Volume slider.       	"pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does.	KDE3: "Enable full duplex operation" deadlocks.	2002-08-31 Karsten Wiese	Version 0.0.3: audio also simplex;	simplifying: iso urbs only 1 packet, melted structs.	ASYNC_UNLINK not used anymore: no more crashes so far.....	for alsa 0.9 rc3.2002-08-09 Karsten Wiese	Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol.	The firmware has been sniffed from win2k us-428 driver 3.09. *   Copyright (c) 2002 - 2004 Karsten Wiese * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA*/#include <sound/driver.h>#include <linux/init.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/interrupt.h>#include <linux/usb.h>#include <sound/core.h>#include <sound/initval.h>#include <sound/pcm.h>#include <sound/rawmidi.h>#include "usx2y.h"#include "usbusx2y.h"#include "usX2Yhwdep.h"MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");MODULE_LICENSE("GPL");MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */module_param_array(index, int, NULL, 0444);MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");module_param_array(id, charp, NULL, 0444);MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");module_param_array(enable, bool, NULL, 0444);MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");static int snd_usX2Y_card_used[SNDRV_CARDS];static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr);static void snd_usX2Y_card_private_free(snd_card_t *card);/*  * pipe 4 is used for switching the lamps, setting samplerate, volumes ....    */static void i_usX2Y_Out04Int(struct urb* urb, struct pt_regs *regs){#ifdef CONFIG_SND_DEBUG	if (urb->status) {		int 		i;		usX2Ydev_t*	usX2Y = urb->context;		for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++);		snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status);	}#endif}static void i_usX2Y_In04Int(struct urb* urb, struct pt_regs *regs){	int			err = 0;	usX2Ydev_t		*usX2Y = urb->context;	us428ctls_sharedmem_t	*us428ctls = usX2Y->us428ctls_sharedmem;	usX2Y->In04IntCalls++;	if (urb->status) {		snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status);		return;	}	//	printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!?	if (us428ctls) {		int diff = -1;		if (-2 == us428ctls->CtlSnapShotLast) {			diff = 0;			memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last));			us428ctls->CtlSnapShotLast = -1;		} else {			int i;			for (i = 0; i < 21; i++) {				if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) {					if (diff < 0)						diff = i;					usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i];				}			}		}		if (0 <= diff) {			int n = us428ctls->CtlSnapShotLast + 1;			if (n >= N_us428_ctl_BUFS  ||  n < 0)				n = 0;			memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0]));			us428ctls->CtlSnapShotDiffersAt[n] = diff;			us428ctls->CtlSnapShotLast = n;			wake_up(&usX2Y->us428ctls_wait_queue_head);		}	}			if (usX2Y->US04) {		if (0 == usX2Y->US04->submitted)			do				err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC);			while (!err && usX2Y->US04->submitted < usX2Y->US04->len);	} else		if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) {			if (us428ctls->p4outLast != us428ctls->p4outSent) {				int j, send = us428ctls->p4outSent + 1;				if (send >= N_us428_p4out_BUFS)					send = 0;				for (j = 0; j < URBS_AsyncSeq  &&  !err; ++j)					if (0 == usX2Y->AS04.urb[j]->status) {						us428_p4out_t *p4out = us428ctls->p4out + send;	// FIXME if more then 1 p4out is new, 1 gets lost.						usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->chip.dev,								  usb_sndbulkpipe(usX2Y->chip.dev, 0x04), &p4out->val.vol, 								  p4out->type == eLT_Light ? sizeof(us428_lights_t) : 5,								  i_usX2Y_Out04Int, usX2Y);						err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC);						us428ctls->p4outSent = send;						break;					}			}		}	if (err)		snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);	urb->dev = usX2Y->chip.dev;	usb_submit_urb(urb, GFP_ATOMIC);}/* * Prepare some urbs */int usX2Y_AsyncSeq04_init(usX2Ydev_t* usX2Y){	int	err = 0,		i;	if (NULL == (usX2Y->AS04.buffer = kmalloc(URB_DataLen_AsyncSeq*URBS_AsyncSeq, GFP_KERNEL))) {		err = -ENOMEM;	} else		for (i = 0; i < URBS_AsyncSeq; ++i) {			if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {				err = -ENOMEM;				break;			}			usb_fill_bulk_urb(	usX2Y->AS04.urb[i], usX2Y->chip.dev,						usb_sndbulkpipe(usX2Y->chip.dev, 0x04),						usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0,						i_usX2Y_Out04Int, usX2Y				);		}	return err;}int usX2Y_In04_init(usX2Ydev_t* usX2Y){	int	err = 0;	if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL)))		return -ENOMEM;	if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL))) {		usb_free_urb(usX2Y->In04urb);		return -ENOMEM;	}	 	init_waitqueue_head(&usX2Y->In04WaitQueue);	usb_fill_int_urb(usX2Y->In04urb, usX2Y->chip.dev, usb_rcvintpipe(usX2Y->chip.dev, 0x4),			 usX2Y->In04Buf, 21,			 i_usX2Y_In04Int, usX2Y,			 10);	err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);	return err;}static void usX2Y_unlinkSeq(snd_usX2Y_AsyncSeq_t* S){	int	i;	for (i = 0; i < URBS_AsyncSeq; ++i) {		if (S[i].urb) {			usb_kill_urb(S->urb[i]);			usb_free_urb(S->urb[i]);			S->urb[i] = NULL;		}	}	kfree(S->buffer);}static struct usb_device_id snd_usX2Y_usb_id_table[] = {	{		.match_flags =	USB_DEVICE_ID_MATCH_DEVICE,		.idVendor =	0x1604,		.idProduct =	USB_ID_US428 	},	{		.match_flags =	USB_DEVICE_ID_MATCH_DEVICE,		.idVendor =	0x1604,		.idProduct =	USB_ID_US122 	}, 	{		.match_flags =	USB_DEVICE_ID_MATCH_DEVICE,		.idVendor =	0x1604,		.idProduct =	USB_ID_US224	},	{ /* terminator */ }};static snd_card_t* usX2Y_create_card(struct usb_device* device){	int		dev;	snd_card_t*	card;	for (dev = 0; dev < SNDRV_CARDS; ++dev)		if (enable[dev] && !snd_usX2Y_card_used[dev])			break;	if (dev >= SNDRV_CARDS)		return NULL;	card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(usX2Ydev_t));	if (!card)		return NULL;	snd_usX2Y_card_used[usX2Y(card)->chip.index = dev] = 1;	card->private_free = snd_usX2Y_card_private_free;	usX2Y(card)->chip.dev = device;	usX2Y(card)->chip.card = card;	init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);	init_MUTEX (&usX2Y(card)->prepare_mutex);	INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list);	strcpy(card->driver, "USB "NAME_ALLCAPS"");	sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");	sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",		card->shortname, 		le16_to_cpu(device->descriptor.idVendor),		le16_to_cpu(device->descriptor.idProduct),		0,//us428(card)->usbmidi.ifnum,		usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum		);	snd_card_set_dev(card, &device->dev);	return card;}static void* usX2Y_usb_probe(struct usb_device* device, struct usb_interface *intf, const struct usb_device_id* device_id){	int		err;	snd_card_t*	card;	if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||	    (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&	     le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&	     le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428) ||	    !(card = usX2Y_create_card(device)))		return NULL;	if ((err = usX2Y_hwdep_new(card, device)) < 0  ||	    (err = snd_card_register(card)) < 0) {		snd_card_free(card);		return NULL;	}	return card;}/* * new 2.5 USB kernel API */static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id){	void *chip;	chip = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id);	if (chip) {		dev_set_drvdata(&intf->dev, chip);		return 0;	} else		return -EIO;}static void snd_usX2Y_disconnect(struct usb_interface *intf){	usX2Y_usb_disconnect(interface_to_usbdev(intf),				 dev_get_drvdata(&intf->dev));}MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);static struct usb_driver snd_usX2Y_usb_driver = { 	.owner =	THIS_MODULE,	.name =		"snd-usb-usx2y",	.probe =	snd_usX2Y_probe,	.disconnect =	snd_usX2Y_disconnect,	.id_table =	snd_usX2Y_usb_id_table,};static void snd_usX2Y_card_private_free(snd_card_t *card){	kfree(usX2Y(card)->In04Buf);	usb_free_urb(usX2Y(card)->In04urb);	if (usX2Y(card)->us428ctls_sharedmem)		snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem));	if (usX2Y(card)->chip.index >= 0  &&  usX2Y(card)->chip.index < SNDRV_CARDS)		snd_usX2Y_card_used[usX2Y(card)->chip.index] = 0;}/* * Frees the device. */static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr){	if (ptr) {		usX2Ydev_t* usX2Y = usX2Y((snd_card_t*)ptr);		struct list_head* p;		usX2Y->chip.shutdown = 1;		usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;		usX2Y_unlinkSeq(&usX2Y->AS04);		usb_kill_urb(usX2Y->In04urb);		snd_card_disconnect((snd_card_t*)ptr);		/* release the midi resources */		list_for_each(p, &usX2Y->chip.midi_list) {			snd_usbmidi_disconnect(p);		}		if (usX2Y->us428ctls_sharedmem) 			wake_up(&usX2Y->us428ctls_wait_queue_head);		snd_card_free((snd_card_t*)ptr);	}}static int __init snd_usX2Y_module_init(void){	return usb_register(&snd_usX2Y_usb_driver);}static void __exit snd_usX2Y_module_exit(void){	usb_deregister(&snd_usX2Y_usb_driver);}module_init(snd_usX2Y_module_init)module_exit(snd_usX2Y_module_exit)

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人高清免费观看| 久久精品亚洲乱码伦伦中文| 91免费国产视频网站| 99精品黄色片免费大全| 成人激情av网| 91天堂素人约啪| 色偷偷久久一区二区三区| 色婷婷香蕉在线一区二区| 欧亚一区二区三区| 欧美久久久久久蜜桃| 日韩亚洲欧美中文三级| 3d动漫精品啪啪| 欧美成人精品1314www| 26uuu精品一区二区三区四区在线| 日韩片之四级片| 精品国产免费人成在线观看| 久久久久久97三级| 国产精品不卡一区| 一区二区三区欧美激情| 婷婷丁香久久五月婷婷| 男人操女人的视频在线观看欧美| 久久99久久久久| 成人小视频在线观看| 一本色道亚洲精品aⅴ| 欧美日韩在线亚洲一区蜜芽| 91精品国产福利| 久久嫩草精品久久久精品一| 国产女人水真多18毛片18精品视频| 国产精品久久久久四虎| 亚洲一区二区欧美激情| 久久超级碰视频| 不卡欧美aaaaa| 欧美老年两性高潮| 久久丝袜美腿综合| 亚洲免费资源在线播放| 日韩电影在线免费| 国产999精品久久久久久| 日本福利一区二区| 日韩欧美国产综合| 中文字幕日韩av资源站| 丝袜诱惑制服诱惑色一区在线观看| 国内成人自拍视频| 色菇凉天天综合网| 欧美不卡一区二区三区| 亚洲欧美综合另类在线卡通| 日韩黄色免费网站| 成人一区在线观看| 91精品国产黑色紧身裤美女| 国产精品午夜免费| 日韩经典一区二区| 99免费精品在线| 欧美电视剧在线观看完整版| 中文字幕一区二区5566日韩| 美腿丝袜亚洲色图| 色又黄又爽网站www久久| 精品久久一区二区| 亚洲国产精品久久艾草纯爱| 国产成人av影院| 欧美一区二区三区免费观看视频| 国产精品乱人伦| 麻豆91在线观看| 欧美熟乱第一页| 国产精品卡一卡二| 久久99在线观看| 欧美日韩在线播放| 国产精品网站导航| 久久精品国内一区二区三区| 欧美综合欧美视频| 中文字幕一区三区| 国产精品综合在线视频| 欧美高清dvd| 亚洲精品一二三区| 高清日韩电视剧大全免费| 欧美一区二区三区四区在线观看 | 欧美一区二区高清| 亚洲欧美区自拍先锋| 国产aⅴ综合色| 精品免费日韩av| 日韩高清在线电影| 欧美亚一区二区| 亚洲美女免费在线| 本田岬高潮一区二区三区| 久久久蜜桃精品| 久久99精品国产麻豆不卡| 欧美人与性动xxxx| 亚洲精品免费播放| av爱爱亚洲一区| 国产精品久久久久影院亚瑟| 国产成人精品www牛牛影视| 亚洲精品一区二区三区蜜桃下载| 日韩电影在线观看电影| 欧美色大人视频| 亚洲主播在线播放| 欧美专区在线观看一区| 亚洲激情综合网| 色综合久久综合网97色综合| 国产乱码精品一区二区三 | 亚洲国产精品黑人久久久| 久久av资源网| 精品国产污污免费网站入口 | 亚洲精品一区二区三区蜜桃下载 | 精品中文字幕一区二区小辣椒| 欧美高清dvd| 日韩精品亚洲一区| 欧美电影在哪看比较好| 性做久久久久久免费观看欧美| 欧美视频一区二区三区| 伊人一区二区三区| 欧美挠脚心视频网站| 强制捆绑调教一区二区| 2020国产成人综合网| 国产老女人精品毛片久久| 国产亚洲污的网站| av中文字幕在线不卡| 亚洲视频在线一区| 欧美亚洲丝袜传媒另类| 日韩中文字幕亚洲一区二区va在线 | av在线不卡电影| 亚洲免费看黄网站| 欧美日韩中文另类| 男人的天堂亚洲一区| 久久久久国产成人精品亚洲午夜 | 欧美不卡在线视频| 国产成人免费网站| 亚洲视频电影在线| 欧美丝袜丝nylons| 狠狠色综合播放一区二区| 欧美激情中文不卡| 欧洲精品视频在线观看| 美女视频黄a大片欧美| 国产日韩欧美一区二区三区乱码| 99综合影院在线| 亚洲电影第三页| 久久久三级国产网站| 96av麻豆蜜桃一区二区| 亚洲一级在线观看| 精品国产免费一区二区三区香蕉| 成人激情免费电影网址| 性做久久久久久免费观看欧美| 26uuu久久天堂性欧美| 96av麻豆蜜桃一区二区| 日本不卡一区二区三区| 国产欧美日韩卡一| 欧美日韩精品一区二区三区四区| 国内精品伊人久久久久影院对白| 中文字幕一区二区在线观看| 91精品国产入口| eeuss鲁片一区二区三区在线看| 五月综合激情网| 中文字幕av一区二区三区高| 欧美日韩一二三区| 国产激情视频一区二区在线观看| 亚洲一区二区视频在线观看| 精品国产三级电影在线观看| 色噜噜久久综合| 国产一区在线观看视频| 亚洲成在线观看| 国产欧美一区二区三区在线看蜜臀| 欧洲精品中文字幕| 成人午夜激情片| 免费久久精品视频| 亚洲精品欧美专区| 国产日韩欧美一区二区三区乱码| 欧美日韩国产乱码电影| 本田岬高潮一区二区三区| 蜜桃91丨九色丨蝌蚪91桃色| 一区二区三区四区在线免费观看| 精品国产免费人成电影在线观看四季 | 色综合久久久久| 国产高清亚洲一区| 乱中年女人伦av一区二区| 亚洲精品va在线观看| 日本一区二区免费在线观看视频| 欧美一区二区三区思思人| 色成人在线视频| eeuss鲁一区二区三区| 韩国成人在线视频| 免费不卡在线视频| 亚洲福利一二三区| 亚洲精品视频在线观看网站| 欧美激情一区二区三区蜜桃视频 | 日韩精品一区二区三区在线播放| 欧美在线不卡视频| 91一区在线观看| 成人国产精品视频| 高清shemale亚洲人妖| 九色porny丨国产精品| 日韩精品成人一区二区三区| 亚洲综合色视频| 伊人色综合久久天天| 18欧美乱大交hd1984| 国产精品理论片| 中文字幕精品综合| 国产欧美日本一区视频| 26uuu国产一区二区三区| 欧美xxxx在线观看| 欧美电影免费观看高清完整版在线观看 | 91精品国产综合久久福利软件 | 亚洲一区二区三区爽爽爽爽爽| 亚洲视频在线一区二区|