Cortical representation of multidimensional handwriting movement and implications for neuroprostheses.
The 4 matches
- [1] § Results › Neural encoding of multidimensional handwriting movements ↔ full model-Fig4F-S8.py, lines 136–213 · score 0.60 · axis velocity, full model, firing rates, Vz, LNP, EMG
- [2] § Methods › Neural encoding: model-based encoding and evaluation ↔ bits_per_spike-Fig4.py, lines 35–66 · score 0.60 · mutual information, bits, firing rate, MI, metric, spike
- [3] § Results › Neural encoding of multidimensional handwriting movements ↔ encoding model-Fig4d-S7.py, lines 67–129 · score 0.56 · encoding model, grip force, firing rates, S7, Vxy, EMG
- [4] § Methods › Neural encoding: model-based encoding and evaluation ↔ full model-Fig4F-S8.py, lines 136–213 · score 0.54 · full model, axis velocity, EMG, pressure, variables, encoding
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 213 lines · 11 KB · GPL-3.0 · 2 matches
- import time
- from scipy.io import loadmat
- import numpy as np
- from torch.utils.data import DataLoader, TensorDataset
- import math
- import scipy.io as io
- from scipy.interpolate import interp1d
- import torch
- from sklearn import preprocessing
- def find_samesegments(arr):
- segments = []
- n = len(arr)
- if n == 0:
- return segments
- start_idx = 0
- for i in range(1, n):
- if arr[i] != arr[start_idx]:
- segments.append((start_idx, i - 1))
- start_idx = i
- segments.append((start_idx, n - 1))
- return segments
- def cal_spike_counts(predict):
- lambdas = predict.detach().cpu().numpy()
- spike_count = np.empty_like(lambdas)
- for i, lmbda_val in enumerate(lambdas):
- if np.isnan(lmbda_val):
- spike_count[i] = np.nan
- else:
- spike_count[i] = np.random.poisson(lmbda_val)
- spike_count = torch.tensor(spike_count, dtype=torch.float).to('cuda')
- return spike_count
- def fit_lnp(variables, spikes,num_epochs):
- dataset = TensorDataset(variables, spikes)
- batch_size = 256
- dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
- # Use a random vector of weights to start (mean 0, sd .1)
- w = torch.normal(0, 0.1, (1,14)).to('cuda').requires_grad_(True)
- optimizer = torch.optim.SGD([w], lr=1e-3)
- scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
- for epoch in range(num_epochs):
- start = time.time()
- total_log_lik = 0
- for X, y in dataloader:
- rate = torch.exp(torch.sum(X * w[0,0:13],dim=1) + w[0,-1]).float()
- # Compute the Poisson log likelihood
- log_lik = -(torch.unsqueeze(y, 0) @ torch.log(rate) - rate.sum())
- optimizer.zero_grad()
- log_lik.backward()
- optimizer.step()
- total_log_lik += log_lik.item()
- scheduler.step()
- avg_loss = total_log_lik / len(dataloader)
- end = time.time()
- print(f"Epoch {epoch + 1}/{num_epochs}, log_lik: {avg_loss:.4f}, time:{end - start:.4f}s")
- return w
- def predict_fr_lnp(variables, theta=None):
- yhat = torch.exp(torch.sum(variables * theta[0,0:13],dim=1) + theta[0,-1])
- return yhat
- # encoding of an example session
- data = loadmat('data0623.mat')
- bined_spk = data['bined_spk'] # neural data
- break_ind = data['break_ind']
- trial_mask = data['trial_mask']
- trial_target = data['trial_target']
- velocity_xy = data['velocity'][:2,:] # average handwriting data
- velocity_z = data['velocity'][2,:]
- Fgrip = data['Fgrip']/1000*9.8 # g -> N
- Fpres = data['Fpres']/1000*9.8
- data = loadmat('0623_s1.mat')
- emg = data['emg_data']
- # neurons with spike rate<1Hz were removed
- firing_rates = bined_spk / 0.2
- neuron_ind = np.where(np.mean(firing_rates,1) >= 1)[0]
- bined_spk = bined_spk[neuron_ind,:]
- num_epochs = 70
- stroke_ind = np.where(break_ind[0]>0)
- velocity_z[stroke_ind[0]] = 0
- # velocity normalization
- v_max = np.nanmax(velocity_xy)
- v_min = np.nanmin(velocity_xy)
- for i in range(velocity_xy.shape[0]):
- for j in range(velocity_xy.shape[1]):
- velocity_xy[i][j] = (2*(velocity_xy[i][j]-v_min)/(v_max-v_min))-1 #[-1,1]
- z_scale = max(np.abs(np.nanmin(velocity_z)),np.abs(np.nanmax(velocity_z)))
- velocity_z = velocity_z/z_scale
- velocity = torch.tensor(np.vstack([velocity_xy, velocity_z])).to('cuda')
- bined_spk = torch.tensor(bined_spk,dtype=torch.float).to('cuda')
- # grip force and pressure normalization
- min_max_scaler = preprocessing.MinMaxScaler(feature_range=(0, 1))
- Fgrip = (min_max_scaler.fit_transform(Fgrip.T)).T
- Fpres = (min_max_scaler.fit_transform(Fpres.T)).T
- # emg normalization
- emg_max = np.max(emg)
- emg_min = np.min(emg)
- for i in range(emg.shape[0]):
- for j in range(emg.shape[1]):
- emg[i][j] = (emg[i][j]-emg_min)/(emg_max-emg_min)
- handwriting_data = torch.cat((velocity,torch.tensor(Fgrip).to('cuda'),torch.tensor(Fpres).to('cuda'),torch.tensor(emg).to('cuda')),dim=0)
- for i_stroke in range(2):
- if i_stroke == 0:
- ind = np.where(break_ind[0] < 0) # cohesion ind
- print('cohesion')
- else:
- ind = np.where(break_ind[0] > 0) # stroke ind
- print('stroke')
- lamda_pre = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.double).to('cuda')# initialize the predicted firing rates
- lamda_pre_delV = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.double).to('cuda') # full moodel-Vel
- lamda_pre_delVz = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.double).to('cuda')# full moodel-Vz
- lamda_pre_delg = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.double).to('cuda') # full moodel-grip
- lamda_pre_delp = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.double).to('cuda') # full moodel-pres
- lamda_pre_delemg = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.double).to('cuda') # full moodel-emg
- spk_predict = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.float).to('cuda')# initialize the predicted spike
- spk_predict_delV = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.float).to('cuda') # full moodel-Vel
- spk_predict_delVz = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.float).to('cuda')# full moodel-Vz
- spk_predict_delg = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.float).to('cuda') # full moodel-grip
- spk_predict_delp = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.float).to('cuda') # full moodel-pres
- spk_predict_delemg = torch.zeros((bined_spk.shape[0], bined_spk.shape[1]), dtype=torch.float).to('cuda') # full moodel-emg
- # encode each neuron in turn
- for channel_num in range(bined_spk.shape[0]):
- bined_spk_channelnum = bined_spk[channel_num, :] # each neuron
- numbers = list(range(1, 31)) # 30 characters in this session
- for count in range(10): # 10 fold
- print(f'neuron:{channel_num + 1},fold:{count + 1}')
- test_numbers = np.array(numbers[:3])
- del numbers[:3]
- character_ind = np.where(trial_target == test_numbers)[0]
- test_indices = np.where(trial_mask[0].reshape(-1, 1) == (character_ind + 1))[0] # character index for test
- tr_target_indices = np.setdiff1d(np.arange(len(trial_mask[0])), test_indices) # character index for training
- test_indices = np.intersect1d(ind, test_indices) # stroke/cohesion index for test
- tr_target_indices = np.intersect1d(ind, tr_target_indices) # stroke/cohesion index for training
- tr_idx = []
- seg_tr = find_samesegments(break_ind[0, tr_target_indices])
- for i_seg in range(len(seg_tr)):
- seg_s = bined_spk_channelnum.T[tr_target_indices[seg_tr[i_seg][0]]:tr_target_indices[seg_tr[i_seg][1]] + 1]
- if torch.any(seg_s.ne(0)):
- tr_idx.append(tr_target_indices[seg_tr[i_seg][0]:seg_tr[i_seg][1] + 1])
- tr_idx = np.concatenate(tr_idx)
- X_test, y_test = handwriting_data.T[test_indices], bined_spk_channelnum[test_indices] # test data
- X_train, y_train = handwriting_data.T[tr_idx], bined_spk_channelnum[tr_idx] # training data
- # remove each variable from the full model
- X_test_delV = X_test[:, 3:]
- X_test_delVz = torch.cat((X_test[:, :2], X_test[:, 3:]), dim=1)
- X_test_delg = torch.cat((X_test[:, :3], X_test[:, 4:]), dim=1)
- X_test_delp = torch.cat((X_test[:, :4], X_test[:, 5:]), dim=1)
- X_test_delemg = X_test[:, :5]
- # Fit LNP model
- theta_lnp = fit_lnp(X_train, y_train, num_epochs) # full model
- theta_lnp_delV = theta_lnp[:, 3:] # remove weights for velocity
- theta_lnp_delVz = torch.cat((theta_lnp[:, :2], theta_lnp[:, 3:]), dim=1) # remove weights for z-axis velocity
- theta_lnp_delg = torch.cat((theta_lnp[:, :3], theta_lnp[:, 4:]), dim=1) # remove weights for grip
- theta_lnp_delp = torch.cat((theta_lnp[:, :4], theta_lnp[:, 5:]), dim=1) # remove weights for pressure
- theta_lnp_delemg = torch.cat((theta_lnp[:, :5], theta_lnp[:, 13:]), dim=1) # remove weights for emg
- # test
- predict = predict_fr_lnp(X_test, theta_lnp) # predicted firing rate
- predict_delV = torch.exp(torch.sum(X_test_delV * theta_lnp_delV[0, :-1], dim=1) + theta_lnp_delV[0, -1])
- predict_delVz = torch.exp(torch.sum(X_test_delVz * theta_lnp_delVz[0, :-1], dim=1) + theta_lnp_delVz[0, -1])
- predict_delg = torch.exp(torch.sum(X_test_delg * theta_lnp_delg[0, :-1], dim=1) + theta_lnp_delg[0, -1])
- predict_delp = torch.exp(torch.sum(X_test_delp * theta_lnp_delp[0, :-1], dim=1) + theta_lnp_delp[0, -1])
- predict_delemg = torch.exp(torch.sum(X_test_delemg * theta_lnp_delemg[0, :-1], dim=1) + theta_lnp_delemg[0, -1])
- lamda_pre[channel_num, test_indices] = predict
- lamda_pre_delV[channel_num, test_indices] = predict_delV
- lamda_pre_delVz[channel_num, test_indices] = predict_delVz
- lamda_pre_delg[channel_num, test_indices] = predict_delg
- lamda_pre_delp[channel_num, test_indices] = predict_delp
- lamda_pre_delemg[channel_num, test_indices] = predict_delemg
- # predicted spike counts
- spk_predict[channel_num, test_indices] = cal_spike_counts(predict)
- spk_predict_delV[channel_num, test_indices] = cal_spike_counts(predict_delV)
- spk_predict_delVz[channel_num, test_indices] = cal_spike_counts(predict_delVz)
- spk_predict_delg[channel_num, test_indices] = cal_spike_counts(predict_delg)
- spk_predict_delp[channel_num, test_indices] = cal_spike_counts(predict_delp)
- spk_predict_delemg[channel_num, test_indices] = cal_spike_counts(predict_delemg)
- # save results
- if i_stroke == 0:
- io.savemat('cohesion/full.mat',{'spk_predict': spk_predict.detach().cpu().numpy(), 'lamda_pre': lamda_pre.detach().cpu().numpy()})
- io.savemat('cohesion/delV.mat', {'spk_predict': spk_predict_delV.detach().cpu().numpy(),'lamda_pre': lamda_pre_delV.detach().cpu().numpy()})
- io.savemat('cohesion/delVz.mat', {'spk_predict': spk_predict_delVz.detach().cpu().numpy(),'lamda_pre': lamda_pre_delVz.detach().cpu().numpy()})
- io.savemat('cohesion/delg.mat', {'spk_predict': spk_predict_delg.detach().cpu().numpy(),'lamda_pre': lamda_pre_delg.detach().cpu().numpy()})
- io.savemat('cohesion/delp.mat', {'spk_predict': spk_predict_delp.detach().cpu().numpy(),'lamda_pre': lamda_pre_delp.detach().cpu().numpy()})
- io.savemat('cohesion/delemg.mat', {'spk_predict': spk_predict_delemg.detach().cpu().numpy(),'lamda_pre': lamda_pre_delemg.detach().cpu().numpy()})
- else:
- io.savemat('stroke/full.mat',{'spk_predict': spk_predict.detach().cpu().numpy(), 'lamda_pre': lamda_pre.detach().cpu().numpy()})
- io.savemat('stroke/delV.mat', {'spk_predict': spk_predict_delV.detach().cpu().numpy(),'lamda_pre': lamda_pre_delV.detach().cpu().numpy()})
- io.savemat('stroke/delVz.mat', {'spk_predict': spk_predict_delVz.detach().cpu().numpy(),'lamda_pre': lamda_pre_delVz.detach().cpu().numpy()})
- io.savemat('stroke/delg.mat', {'spk_predict': spk_predict_delg.detach().cpu().numpy(),'lamda_pre': lamda_pre_delg.detach().cpu().numpy()})
- io.savemat('stroke/delp.mat', {'spk_predict': spk_predict_delp.detach().cpu().numpy(),'lamda_pre': lamda_pre_delp.detach().cpu().numpy()})
- io.savemat('stroke/delemg.mat', {'spk_predict': spk_predict_delemg.detach().cpu().numpy(),'lamda_pre': lamda_pre_delemg.detach().cpu().numpy()})
full model-Fig4F-S8.py at commit 97b0bc6, under GPL-3.0 · at the source
Overview
- The State Key Lab of Brain-Machine Intelligence, Zhejiang University,Hangzhou, China
- Nanhu Brain-Computer Interface Institute, Hangzhou, China
- Department of Biomedical Engineering, Zhejiang University,Hangzhou, China
- Department of Neurosurgery, Second Affiliated Hospital of Zhejiang University School of Medicine,Hangzhou, China
- College of Computer Science and Technology, Zhejiang University,Hangzhou, China
Abstract
The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.
Repository
Its files are read in the Code ↔ Paper reader above, with 4 matches between paragraphs and lines of code.
yaoyao-hao/handwriting_codec
97b0bc6b3f4f6930986bc4684f7a4e42efd148f8, 3 December 2025Availability: 1 check, the latest on 30 September 2026: the link answers
- 30 September 2026: the link answers
7 files
- bits_per_spike-Fig4.py, Python, 66 lines, 1 match
- dtw_recognition-Fig5.py, Python, 149 lines
- encoding model-Fig4d-S7.py, Python, 183 lines, 1 match
- full model-Fig4F-S8.py, Python, 213 lines, 2 matches
- handwriting_decoding-Fig
5.py , Python, 188 lines - LICENSE, License, 674 lines
- README.md, Text, 52 lines
Code availability statement
The paper has a code availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:
- it points to the authors' code: yaoyao-hao/
handwriting_codec
Read it in the paper: doi.org/10.1038/s41467-026-70536-7.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 5 scripts, each with its path and the digest of its content;
- 4 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
Datasets cited
- zenodo:18399428, at Zenodo; found in “Data availability”
Data availability statement
The paper has a data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:
- it points to a dataset: Zenodo 18399428
Read it in the paper: doi.org/10.1038/s41467-026-70536-7.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 30 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 9 authors, 2 keywords, 11 MeSH terms, 3 funders, 44 references.
Cite
This paper
Wang, Z., Xu, G., Yu, B., Xu, K., Zhu, J., Pan, G., Zhang, J., Wang, Y., & Hao, Y. (2026). Cortical representation of multidimensional handwriting movement and implications for neuroprostheses. Nature communications, 17(1), 3966. https://
BibTeX
@article{wang2026cortica
author = {Wang, Zebin and Xu, Guangxiang and Yu, Bowen and Xu, Kedi and Zhu, Junming and Pan, Gang and Zhang, Jianmin and Wang, Yueming and Hao, Yaoyao},
title = {{Cortical representation of multidimensional handwriting movement and implications for neuroprostheses}},
journal = {Nature communications},
year = {2026},
month = mar,
volume = {17},
number = {1},
pages = {3966},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/
url = {https://
pmid = {41832195},
pmcid = {PMC13133357}
}
RIS
TY - JOUR
AU - Wang, Zebin
AU - Xu, Guangxiang
AU - Yu, Bowen
AU - Xu, Kedi
AU - Zhu, Junming
AU - Pan, Gang
AU - Zhang, Jianmin
AU - Wang, Yueming
AU - Hao, Yaoyao
TI - Cortical representation of multidimensional handwriting movement and implications for neuroprostheses
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/
VL - 17
IS - 1
SP - 3966
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1038/
"type": "article-journal",
"title": "Cortical representation of multidimensional handwriting movement and implications for neuroprostheses",
"container-title": "Nature communications",
"author": [
{
"family": "Wang",
"given": "Zebin"
},
{
"family": "Xu",
"given": "Guangxiang"
},
{
"family": "Yu",
"given": "Bowen"
},
{
"family": "Xu",
"given": "Kedi"
},
{
"family": "Zhu",
"given": "Junming"
},
{
"family": "Pan",
"given": "Gang"
},
{
"family": "Zhang",
"given": "Jianmin"
},
{
"family": "Wang",
"given": "Yueming"
},
{
"family": "Hao",
"given": "Yaoyao"
}
],
"container-title-short":
"volume": "17",
"issue": "1",
"page": "3966",
"DOI": "10.1038/
"PMID": "41832195",
"PMCID": "PMC13133357",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
14
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s42003-026-10144-9 [code]
- Low-power differencing feature extracts spiking-band activities for high-performance intracortical brain-computer interfaces.Journal: Communications biologyIn common: PyTorch, scikit-learn, SciPy, 1 other tool, 6 references, 3 authors
- [2] doi:10.1038/s41467-026-71267-5 [code]
- Human-like cognitive generalization for large models via mental representation-guided supervision.Journal: Nature communicationsIn common: PyTorch, scikit-learn, SciPy, 1 other tool, 2 authors
- [3] doi:10.1126/sciadv.adw3876 [code]
- Intracortical brain-computer interface for navigation in virtual reality in macaque monkeys.Journal: Science advancesIn common: scikit-learn, SciPy, NumPy, systems, 4 references
- [4] doi:10.1038/s41591-026-04414-6 [code]
- Long-term independent use of an intracortical brain-computer interface for speech and cursor control.Journal: Nature medicineIn common: SciPy, NumPy, 4 references
- [5] doi:10.1162/imag.a.1265
- Neurophysiological mechanisms of optimized graphomotor performance in biscriptuals.Journal: Imaging neuroscience (Cambridge, Mass.)In common: 4 references
- [6] doi:10.1038/s41586-026-10653-x [code]
- A mosaic of whole-body representations on the human precentral gyrus.Journal: NatureIn common: PyTorch, scikit-learn, SciPy, 1 other tool, systems, 2 references
- [7] doi:10.1016/j.neuroimage.2026.121837
- Optimal location for gesture decoding in the sensorimotor cortex and implications for brain-computer interface research.Journal: NeuroImageIn common: systems, 4 references
- [8] doi:10.1038/s41467-026-75455-1 [code]
- Shared latent representations of speech production for cross-patient speech decoding.Journal: Nature communicationsIn common: PyTorch, scikit-learn, SciPy, 1 other tool, 2 references
- [9] doi:10.1038/s41593-026-02258-4 [code]
- Laminar organization of cellular microcircuits modulating human interictal epileptiform discharges.Journal: Nature neuroscienceIn common: scikit-learn, SciPy, NumPy, systems, 2 references
- [10] doi:10.1038/s41467-026-75588-3 [code]
- Frequency-dependent effects of motor thalamus deep brain stimulation on speech and swallowing.Journal: Nature communicationsIn common: 4 references
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 5 scripts, and 4 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:84cfa5b6251b5873…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
