forked from M-Labs/web2019
Compare commits
13 Commits
5c449d9502
...
5e5246e8ae
Author | SHA1 | Date |
---|---|---|
Egor Savkin | 5e5246e8ae | |
Egor Savkin | 60f8574a8c | |
Egor Savkin | 1d8d31f0a2 | |
Egor Savkin | 4acf38ba13 | |
Egor Savkin | 4ac521db7f | |
Egor Savkin | f087a00cee | |
Sébastien Bourdeauducq | f69102fa0e | |
Egor Savkin | 0d978c1e22 | |
Sébastien Bourdeauducq | 76bc87ce5c | |
Sébastien Bourdeauducq | 3987343e16 | |
Sébastien Bourdeauducq | 8a12d35c06 | |
Sébastien Bourdeauducq | d2ae816cb0 | |
Egor Savkin | bcdf005896 |
|
@ -33,6 +33,7 @@ Typical countries where this situation happens and suitable distributor contacts
|
||||||
* China (mainland): kitty-zheng@kehua-trade.com
|
* China (mainland): kitty-zheng@kehua-trade.com
|
||||||
* Japan: hishida@symphotony.com or h_yamamoto@autex-inc.co.jp
|
* Japan: hishida@symphotony.com or h_yamamoto@autex-inc.co.jp
|
||||||
* India: sale.sannidhi@gmail.com
|
* India: sale.sannidhi@gmail.com
|
||||||
|
* Thailand: info@irct.co.th or thayika@ryts-instruments.co.th
|
||||||
|
|
||||||
You are responsible for paying distributor fees and we do not grant discounts on the basis of requiring a distributor. On our side, we do not mandate the use of any distributor and we can ship directly to you or via another distributor of your choosing not listed here. Generally, you may solve the import problems created by customs and other bureaucracy in any way that you deem acceptable.
|
You are responsible for paying distributor fees and we do not grant discounts on the basis of requiring a distributor. On our side, we do not mandate the use of any distributor and we can ship directly to you or via another distributor of your choosing not listed here. Generally, you may solve the import problems created by customs and other bureaucracy in any way that you deem acceptable.
|
||||||
|
|
||||||
|
@ -52,7 +53,25 @@ M-Labs offers discounts in the following cases:
|
||||||
* Advanced hobbyist and amateur use. Please describe your project when applying for the discount and provide supporting evidence (e.g. publications of past projects, personal website, copy of amateur radio license, ...).
|
* Advanced hobbyist and amateur use. Please describe your project when applying for the discount and provide supporting evidence (e.g. publications of past projects, personal website, copy of amateur radio license, ...).
|
||||||
|
|
||||||
We reserve the right of final decision regarding discount eligibility and amount.
|
We reserve the right of final decision regarding discount eligibility and amount.
|
||||||
|
|
||||||
|
##### I am on a really tight budget, what can I do?
|
||||||
|
|
||||||
|
You can build a useful ARTIQ system and spend very little money by running the open-source code on mass-produced low-cost electronics that were not made for this purpose. For example, in theory the [Colorlight-75E](https://hackaday.com/2020/01/24/new-part-day-led-driver-is-fpga-dev-board-in-disguise/) and [EBAZ4205](https://github.com/xjtuecho/EBAZ4205) can be used as core devices, and the Taobao shop [ZONRI](https://world.taobao.com/dianpu/73267337.htm) sells many inexpensive boards that can be useful as I/O peripherals such as DDS and data converters.
|
||||||
|
|
||||||
|
This is not a turn-key solution; experience with electronics, FPGA, and software development is required, and you will have to spend some time studying the code, porting it to these boards, writing drivers, and building hardware adapters.
|
||||||
|
|
||||||
|
See also [193THz.com](https://193THz.com) for ideas about low-cost homebrew laser systems.
|
||||||
|
|
||||||
|
##### Do you have a warranty?
|
||||||
|
|
||||||
|
For most products, we offer a 1-year warranty against manufacturing defects.
|
||||||
|
|
||||||
|
##### What should I do if I need technical support, or there is a problem with my order?
|
||||||
|
|
||||||
|
Please contact us at helpdesk@m-labs.hk.
|
||||||
|
|
||||||
|
If you have contacted the helpdesk and your issue cannot be satisfactorily resolved, then contact sb@m-labs.hk or text +852 65873703. Mention your helpdesk ticket number.
|
||||||
|
|
||||||
##### What are your payment terms?
|
##### What are your payment terms?
|
||||||
|
|
||||||
For most established institutions (determined at our discretion), we offer Net 15 and Net 30 terms after delivery. Please enquire from your institutional email address to help us determine your eligibility for these terms.
|
For most established institutions (determined at our discretion), we offer Net 15 and Net 30 terms after delivery. Please enquire from your institutional email address to help us determine your eligibility for these terms.
|
||||||
|
@ -73,6 +92,20 @@ Yes, however processing credit cards is expensive and you need to cover the cost
|
||||||
|
|
||||||
Exclusivity is subject to contractual minimum order volumes determined at our discretion, but generally exceeding USD 300,000.00 per year for most countries.
|
Exclusivity is subject to contractual minimum order volumes determined at our discretion, but generally exceeding USD 300,000.00 per year for most countries.
|
||||||
|
|
||||||
|
##### What is m-labs-intl.com?
|
||||||
|
|
||||||
|
[m-labs-intl.com](https://m-labs-intl.com) is a mirror site operated by us and hosted in the USA by Hetzner. It is useful in situations where your institution or local authorities block access to Hong Kong websites (.hk domains and/or Hong Kong IP addresses). To our knowledge, no internet blocking is done on the Hong Kong side other than through ISP DNS resolvers, which we do not use and which does not affect your access to our website.
|
||||||
|
|
||||||
|
Some features are currently not available on the mirror site, and you may use a VPN or another circumvention measure of your choice to access these as required.
|
||||||
|
|
||||||
|
##### Why are you ignoring my emails?
|
||||||
|
|
||||||
|
If you are using the email server of a large institution, be aware that some may silently drop emails sent to .hk email addresses and/or to servers located in Hong Kong.
|
||||||
|
|
||||||
|
Try sending your message from your personal address (for example Gmail, Outlook and Yahoo do not block our email system), or to the same email address at the m-labs-intl.com domain (for example, sales@m-labs-intl.com or sb@m-labs-intl.com).
|
||||||
|
|
||||||
|
Alternatively, you may use our [contact phone numbers](../office/), which are also registered with several popular messaging apps.
|
||||||
|
|
||||||
##### We are a recruitment firm. Can we help you find talent?
|
##### We are a recruitment firm. Can we help you find talent?
|
||||||
|
|
||||||
No.
|
No.
|
||||||
|
|
|
@ -270,6 +270,7 @@ The 4624 AWG "Phaser" is a quad channel 1.25 GS/s RF generator card with dual IQ
|
||||||
|
|
||||||
- 2x 1.25 GS/s IQ upconverters.
|
- 2x 1.25 GS/s IQ upconverters.
|
||||||
- dual IQ mixer + 0.3 GHz to 4.8 GHz VCO + PLL.
|
- dual IQ mixer + 0.3 GHz to 4.8 GHz VCO + PLL.
|
||||||
|
- up to 16 dynamic tones per channel using <a href="https://github.com/quartiq/miqro-sim" target="_blank" rel="noopener noreferrer">MIQRO gateware</a> (available separately from QUARTIQ).
|
||||||
- 31.5 dB range digital step attenuator (similar to Urukul).
|
- 31.5 dB range digital step attenuator (similar to Urukul).
|
||||||
- 2 channels of 5 MS/s ADC (similar to Sampler).
|
- 2 channels of 5 MS/s ADC (similar to Sampler).
|
||||||
- Artix-7 FPGA.
|
- Artix-7 FPGA.
|
||||||
|
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 13 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 117 KiB |
File diff suppressed because one or more lines are too long
|
@ -5,7 +5,8 @@ import {SummaryPopup} from "./options/SummaryPopup";
|
||||||
|
|
||||||
export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
|
export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
|
||||||
const crate_id = useShopStore((state) => state.crates[crate_index].id);
|
const crate_id = useShopStore((state) => state.crates[crate_index].id);
|
||||||
const options = useShopStore((state) => state.crates[crate_index].items[card_index].options);
|
const use_options = useShopStore((state) => state.crateParams(state.crates[crate_index].crate_mode).options);
|
||||||
|
const options = useShopStore((state) => state.crates[crate_index].items[card_index][use_options]);
|
||||||
const options_data = useShopStore((state) => state.crates[crate_index].items[card_index].options_data);
|
const options_data = useShopStore((state) => state.crates[crate_index].items[card_index].options_data);
|
||||||
const card_size = useShopStore((state) => state.crates[crate_index].items[card_index].size);
|
const card_size = useShopStore((state) => state.crates[crate_index].items[card_index].size);
|
||||||
const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id);
|
const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id);
|
||||||
|
@ -53,7 +54,8 @@ export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
|
||||||
|
|
||||||
export function OptionsSummaryWrapper({crate_index, card_index}) {
|
export function OptionsSummaryWrapper({crate_index, card_index}) {
|
||||||
const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id);
|
const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id);
|
||||||
const options = useShopStore((state) => state.crates[crate_index].items[card_index].options);
|
const use_options = useShopStore((state) => state.crateParams(state.crates[crate_index].crate_mode).options);
|
||||||
|
const options = useShopStore((state) => state.crates[crate_index].items[card_index][use_options]);
|
||||||
const options_data = useShopStore((state) => state.crates[crate_index].items[card_index].options_data);
|
const options_data = useShopStore((state) => state.crates[crate_index].items[card_index].options_data);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -25,7 +25,8 @@ export function ProductCartItem({card_index, crate_index, first, last}) {
|
||||||
const card_counted_resources = useShopStore(state => state.crates[crate_index].items[card_index].counted_resources, compareObjectsEmptiness);
|
const card_counted_resources = useShopStore(state => state.crates[crate_index].items[card_index].counted_resources, compareObjectsEmptiness);
|
||||||
|
|
||||||
const highlighted = useShopStore((state) => state.crates[crate_index].id === state.highlighted.crate && card_index === state.highlighted.card);
|
const highlighted = useShopStore((state) => state.crates[crate_index].id === state.highlighted.crate && card_index === state.highlighted.card);
|
||||||
const options_disabled = useShopStore((state) => !!state.crateParams(state.crates[crate_index].crate_mode).warnings_disabled);
|
const warnings_disabled = useShopStore((state) => !!state.crateParams(state.crates[crate_index].crate_mode).warnings_disabled);
|
||||||
|
const use_options = useShopStore((state) => state.crateParams(state.crates[crate_index].crate_mode).options);
|
||||||
const crate_id = useShopStore((state) => state.crates[crate_index].id);
|
const crate_id = useShopStore((state) => state.crates[crate_index].id);
|
||||||
const setHighlight = useShopStore((state) => state.highlightCard);
|
const setHighlight = useShopStore((state) => state.highlightCard);
|
||||||
const removeHighlight = useShopStore((state) => state.highlightReset);
|
const removeHighlight = useShopStore((state) => state.highlightReset);
|
||||||
|
@ -35,9 +36,9 @@ export function ProductCartItem({card_index, crate_index, first, last}) {
|
||||||
console.log("ProductCartItem renders: ", renderCount)
|
console.log("ProductCartItem renders: ", renderCount)
|
||||||
|
|
||||||
|
|
||||||
const options = !options_disabled && card && card.options && card.options.length > 0;
|
const options = use_options && card && card[use_options] && card[use_options].length > 0;
|
||||||
const warnings = !options_disabled && card_show_warnings && card_show_warnings.length > 0;
|
const warnings = !warnings_disabled && card_show_warnings && card_show_warnings.length > 0;
|
||||||
const resources = !options_disabled && card_counted_resources && card_counted_resources.length > 0;
|
const resources = !warnings_disabled && card_counted_resources && card_counted_resources.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Draggable draggableId={card.id} index={card_index}>
|
<Draggable draggableId={card.id} index={card_index}>
|
||||||
|
|
|
@ -23,16 +23,16 @@ export function SummaryCrateCard({crate_index, card_index}) {
|
||||||
(a, b) => a.id === b.id);
|
(a, b) => a.id === b.id);
|
||||||
const card_show_warnings = useShopStore(state => state.crates[crate_index].items[card_index].show_warnings, compareObjectsEmptiness);
|
const card_show_warnings = useShopStore(state => state.crates[crate_index].items[card_index].show_warnings, compareObjectsEmptiness);
|
||||||
const card_options_data = useShopStore(state => state.crates[crate_index].items[card_index].options_data, compareObjectsEmptiness);
|
const card_options_data = useShopStore(state => state.crates[crate_index].items[card_index].options_data, compareObjectsEmptiness);
|
||||||
const options_disabled = useShopStore((state) => !!state.crateParams(state.crates[crate_index].crate_mode).warnings_disabled);
|
const warnings_disabled = useShopStore((state) => !!state.crateParams(state.crates[crate_index].crate_mode).warnings_disabled);
|
||||||
|
const use_options = useShopStore((state) => state.crateParams(state.crates[crate_index].crate_mode).options);
|
||||||
|
|
||||||
// #!render_count
|
// #!render_count
|
||||||
console.log("SummaryCrateCard renders: ", renderCount)
|
console.log("SummaryCrateCard renders: ", renderCount)
|
||||||
|
|
||||||
|
|
||||||
const options = !options_disabled && card && card.options && card.options.length > 0;
|
const options = use_options && card && card[use_options] && card[use_options].length > 0;
|
||||||
const options_data = !options_disabled && card_options_data && Object.keys(card_options_data).length > 0;
|
const options_data = card_options_data && Object.keys(card_options_data).length > 0;
|
||||||
const warnings = !options_disabled && card_show_warnings && card_show_warnings.length > 0;
|
const warnings = !warnings_disabled && card_show_warnings && card_show_warnings.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
|
|
|
@ -65,12 +65,13 @@ export function CratesToJSON(crates) {
|
||||||
const crateOptions = useShopStore.getState().crate_options;
|
const crateOptions = useShopStore.getState().crate_options;
|
||||||
const orderOptions = useShopStore.getState().order_options;
|
const orderOptions = useShopStore.getState().order_options;
|
||||||
const orderOptionsData = useShopStore.getState().order_options_data;
|
const orderOptionsData = useShopStore.getState().order_options_data;
|
||||||
|
const crateParams = useShopStore.getState().crateParams;
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
// additional fields can go here
|
// additional fields can go here
|
||||||
crates: Array.from(crates.map((crate, _i) => ({
|
crates: Array.from(crates.map((crate, _i) => ({
|
||||||
items: Array.from(crate.items.map((card, _) => ({
|
items: Array.from(crate.items.map((card, _) => ({
|
||||||
pn: card.name_number,
|
pn: card.name_number,
|
||||||
options: (card.options_data && card.options) ? FilterOptions(card.options, card.options_data) : null
|
options: (card.options_data && card[crateParams(crate.crate_mode).options]) ? FilterOptions(card[crateParams(crate.crate_mode).options], card.options_data) : null
|
||||||
}))),
|
}))),
|
||||||
type: crate.crate_mode,
|
type: crate.crate_mode,
|
||||||
options: FilterOptions(crateOptions, crate.options_data)
|
options: FilterOptions(crateOptions, crate.options_data)
|
||||||
|
|
|
@ -16,6 +16,35 @@ const ipv6 = (params) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hostname = (params) => {
|
||||||
|
const maxHostnameLength = 253;
|
||||||
|
const maxLabelLength = 63;
|
||||||
|
const labelRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
|
||||||
|
|
||||||
|
return (text) => {
|
||||||
|
if (text.length > maxHostnameLength) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const labels = text.split('.');
|
||||||
|
for (const label of labels) {
|
||||||
|
if (label.length < 1
|
||||||
|
|| label.length > maxLabelLength
|
||||||
|
|| !labelRegex.test(label)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ipv4OrHost = (params) => {
|
||||||
|
const hostnameLocal = hostname(params);
|
||||||
|
const ipv4Local = ipv4(params);
|
||||||
|
return (text) => {
|
||||||
|
return ipv4Local(text) || hostnameLocal(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ipv4or6 = (params) => {
|
const ipv4or6 = (params) => {
|
||||||
const ipv4Local = ipv4(params);
|
const ipv4Local = ipv4(params);
|
||||||
const ipv6Local = ipv6(params);
|
const ipv6Local = ipv6(params);
|
||||||
|
@ -47,5 +76,7 @@ export const Validation = {
|
||||||
ipv4: ipv4,
|
ipv4: ipv4,
|
||||||
ipv6: ipv6,
|
ipv6: ipv6,
|
||||||
ipv4or6: ipv4or6,
|
ipv4or6: ipv4or6,
|
||||||
|
hostname: hostname,
|
||||||
|
ipv4OrHost: ipv4OrHost,
|
||||||
frequency: frequency
|
frequency: frequency
|
||||||
};
|
};
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import {createWithEqualityFn} from "zustand/traditional";
|
import {createWithEqualityFn} from "zustand/traditional";
|
||||||
import {DATA as shared_data, itemsUnfoldedList, API_RFQ} from "./utils";
|
import {DATA as shared_data, itemsUnfoldedList, API_RFQ} from "./utils";
|
||||||
import {FillExtCrateData, FillExtOrderData, true_type_of} from "./options/utils";
|
import {FillExtCrateData, FillExtOrderData} from "./options/utils";
|
||||||
import {v4 as uuidv4} from "uuid";
|
import {v4 as uuidv4} from "uuid";
|
||||||
import {FillResources} from "./count_resources";
|
import {FillResources} from "./count_resources";
|
||||||
import {FillExtCardData} from "./options/utils";
|
import {FillExtCardData} from "./options/utils";
|
||||||
|
@ -19,6 +19,10 @@ const cards_to_pn_map = (cards) => {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toArray = (arg) => {
|
||||||
|
return Array.isArray(arg) ? arg : [arg];
|
||||||
|
};
|
||||||
|
|
||||||
const useCatalog = ((set, get) => ({
|
const useCatalog = ((set, get) => ({
|
||||||
cards: shared_data.items,
|
cards: shared_data.items,
|
||||||
groups: shared_data.columns.catalog,
|
groups: shared_data.columns.catalog,
|
||||||
|
@ -385,7 +389,7 @@ const useCart = ((set, get) => ({
|
||||||
})),
|
})),
|
||||||
setActiveCrate: (id) => set(state => ({active_crate: id})),
|
setActiveCrate: (id) => set(state => ({active_crate: id})),
|
||||||
_addCardFromCatalog: (crate_to, index_from, index_to) => set(state => {
|
_addCardFromCatalog: (crate_to, index_from, index_to) => set(state => {
|
||||||
const take_from = (true_type_of(index_from) === "array" ? index_from : [index_from]).map((item, _i) => (state.cards_list[item]));
|
const take_from = toArray(index_from).map((item, _i) => (state.cards_list[item]));
|
||||||
const dest = crate_to || state.active_crate;
|
const dest = crate_to || state.active_crate;
|
||||||
if (!dest) return {};
|
if (!dest) return {};
|
||||||
return {
|
return {
|
||||||
|
@ -496,10 +500,11 @@ const useCart = ((set, get) => ({
|
||||||
fillExtData: (crate_id) => set(state => ({
|
fillExtData: (crate_id) => set(state => ({
|
||||||
crates: state.crates.map((crate, _i) => {
|
crates: state.crates.map((crate, _i) => {
|
||||||
if (crate_id === crate.id) {
|
if (crate_id === crate.id) {
|
||||||
|
const options_name = state.crateParams(crate.crate_mode).options;
|
||||||
let itemsCopy = Array.from(crate.items);
|
let itemsCopy = Array.from(crate.items);
|
||||||
|
|
||||||
itemsCopy = itemsCopy.map((item, index) => {
|
itemsCopy = itemsCopy.map((item, index) => {
|
||||||
if (!item.options) return item;
|
if (!item[options_name]) return item;
|
||||||
if (!item.options_data) item.options_data = {};
|
if (!item.options_data) item.options_data = {};
|
||||||
item.options_data.ext_data = FillExtCardData(itemsCopy, index);
|
item.options_data.ext_data = FillExtCardData(itemsCopy, index);
|
||||||
return item;
|
return item;
|
||||||
|
@ -553,10 +558,12 @@ const useCart = ((set, get) => ({
|
||||||
delCrate: (id) => {
|
delCrate: (id) => {
|
||||||
get()._delCrate(id);
|
get()._delCrate(id);
|
||||||
get().fillOrderExtData();
|
get().fillOrderExtData();
|
||||||
|
get()._updateTotalOrderPrice();
|
||||||
},
|
},
|
||||||
|
|
||||||
addCardFromCatalog: (crate_to, index_from, index_to, just_mounted) => {
|
addCardFromCatalog: (crate_to, index_from, index_to, just_mounted) => {
|
||||||
const dest = crate_to || get().active_crate;
|
const isCrateless = toArray(index_from).some(value => get().getCardDescription(value).crateless === true);
|
||||||
|
const dest = isCrateless ? "spare" : crate_to || get().active_crate;
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
console.warn("No destination");
|
console.warn("No destination");
|
||||||
get().noDestinationWarning();
|
get().noDestinationWarning();
|
||||||
|
@ -594,6 +601,7 @@ const useCart = ((set, get) => ({
|
||||||
clearCrate: (id) => {
|
clearCrate: (id) => {
|
||||||
get()._clearCrate(id);
|
get()._clearCrate(id);
|
||||||
get().fillWarnings(id);
|
get().fillWarnings(id);
|
||||||
|
get()._updateTotalOrderPrice();
|
||||||
},
|
},
|
||||||
|
|
||||||
updateOptions: (crate_id, index, new_options) => {
|
updateOptions: (crate_id, index, new_options) => {
|
||||||
|
|
|
@ -6,20 +6,23 @@ const shop_data = {
|
||||||
id: 'rack',
|
id: 'rack',
|
||||||
name: 'Rack mountable crate',
|
name: 'Rack mountable crate',
|
||||||
price: 550,
|
price: 550,
|
||||||
hp: 84
|
hp: 84,
|
||||||
|
options: "options"
|
||||||
},
|
},
|
||||||
desktop: {
|
desktop: {
|
||||||
id: 'desktop',
|
id: 'desktop',
|
||||||
name: 'Desktop crate',
|
name: 'Desktop crate',
|
||||||
price: 500,
|
price: 500,
|
||||||
hp: 42
|
hp: 42,
|
||||||
|
options: "options"
|
||||||
},
|
},
|
||||||
no_crate: {
|
no_crate: {
|
||||||
id: 'no_crate',
|
id: 'no_crate',
|
||||||
name: 'Spare cards',
|
name: 'Spare items',
|
||||||
price: 0,
|
price: 0,
|
||||||
hp: -1,
|
hp: -1,
|
||||||
warnings_disabled: true
|
warnings_disabled: true,
|
||||||
|
options: "crateless_options"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
crateModeOrder: [
|
crateModeOrder: [
|
||||||
|
@ -751,6 +754,7 @@ const shop_data = {
|
||||||
specs: [
|
specs: [
|
||||||
'2x 1.25 GS/s IQ upconverters.',
|
'2x 1.25 GS/s IQ upconverters.',
|
||||||
'dual IQ mixer + 0.3 GHz to 4.8 GHz VCO + PLL.',
|
'dual IQ mixer + 0.3 GHz to 4.8 GHz VCO + PLL.',
|
||||||
|
'up to 16 dynamic tones using MIQRO gateware (available separately from QUARTIQ).',
|
||||||
'31.5 dB range digital step attenuator (similar to Urukul).',
|
'31.5 dB range digital step attenuator (similar to Urukul).',
|
||||||
'2 channels of 5 MS/s ADC (similar to Sampler).',
|
'2 channels of 5 MS/s ADC (similar to Sampler).',
|
||||||
'Artix-7 FPGA.',
|
'Artix-7 FPGA.',
|
||||||
|
@ -926,6 +930,27 @@ const shop_data = {
|
||||||
idc: 1
|
idc: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'idc-mcx-adapter': {
|
||||||
|
id: 'idc-mcx-adapter',
|
||||||
|
name: 'MCX-IDC',
|
||||||
|
name_number: '5538',
|
||||||
|
name_codename: '',
|
||||||
|
price: 320,
|
||||||
|
image: '/images/shop/graphic-03_MCX-IDC32.svg',
|
||||||
|
specs: [
|
||||||
|
'Breaks out analog signals from Zotino or HD68-IDC to MCX connectors.',
|
||||||
|
'Each card provides 32 channels.',
|
||||||
|
],
|
||||||
|
size: 'big',
|
||||||
|
type: 'idc-bnc',
|
||||||
|
warnings: [
|
||||||
|
"no_idc_source"
|
||||||
|
],
|
||||||
|
consumes: {
|
||||||
|
hp: 8,
|
||||||
|
idc: 4
|
||||||
|
}
|
||||||
|
},
|
||||||
'hd68-idc-adapter': {
|
'hd68-idc-adapter': {
|
||||||
id:'hd68-idc-adapter',
|
id:'hd68-idc-adapter',
|
||||||
name: 'HD68-IDC',
|
name: 'HD68-IDC',
|
||||||
|
@ -1081,10 +1106,24 @@ const shop_data = {
|
||||||
validator: {name: "ipv4or6"},
|
validator: {name: "ipv4or6"},
|
||||||
fallback: {text: "DHCP", checked: false},
|
fallback: {text: "DHCP", checked: false},
|
||||||
tip: "Set up IP address used by the device"}},
|
tip: "Set up IP address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
||||||
{type: "Switch", args: {title: "Term #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
{type: "Switch", args: {title: "Term #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
||||||
{type: "Switch", args: {title: "Term #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
{type: "Switch", args: {title: "Term #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
||||||
],
|
],
|
||||||
|
crateless_options: [
|
||||||
|
{type: "SwitchLine", args: {title: "IP", outvar: "ip",
|
||||||
|
validator: {name: "ipv4or6"},
|
||||||
|
fallback: {text: "DHCP", checked: false},
|
||||||
|
tip: "Set up IP address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
|
],
|
||||||
options_class: "stabilizer",
|
options_class: "stabilizer",
|
||||||
size: 'small',
|
size: 'small',
|
||||||
warnings: [
|
warnings: [
|
||||||
|
@ -1115,10 +1154,24 @@ const shop_data = {
|
||||||
validator: {name: "ipv4or6"},
|
validator: {name: "ipv4or6"},
|
||||||
fallback: {text: "DHCP", checked: false},
|
fallback: {text: "DHCP", checked: false},
|
||||||
tip: "Set up IP address used by the device"}},
|
tip: "Set up IP address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
||||||
{type: "Switch", args: {title: "Term #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
{type: "Switch", args: {title: "Term #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
||||||
{type: "Switch", args: {title: "Term #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
{type: "Switch", args: {title: "Term #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
||||||
],
|
],
|
||||||
|
crateless_options: [
|
||||||
|
{type: "SwitchLine", args: {title: "IP", outvar: "ip",
|
||||||
|
validator: {name: "ipv4or6"},
|
||||||
|
fallback: {text: "DHCP", checked: false},
|
||||||
|
tip: "Set up IP address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
|
],
|
||||||
options_class: "stabilizer",
|
options_class: "stabilizer",
|
||||||
size: 'small',
|
size: 'small',
|
||||||
warnings: [
|
warnings: [
|
||||||
|
@ -1204,7 +1257,25 @@ const shop_data = {
|
||||||
'100Base-T Ethernet with PoE.'
|
'100Base-T Ethernet with PoE.'
|
||||||
],
|
],
|
||||||
options: [
|
options: [
|
||||||
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}}
|
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
||||||
|
{type: "SwitchLine", args: {title: "Static IPv4", outvar: "ip",
|
||||||
|
validator: {name: "ipv4"},
|
||||||
|
fallback: {text: "0.0.0.0", checked: false},
|
||||||
|
tip: "Set up static IPv4 address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
|
],
|
||||||
|
crateless_options: [
|
||||||
|
{type: "SwitchLine", args: {title: "Static IPv4", outvar: "ip",
|
||||||
|
validator: {name: "ipv4"},
|
||||||
|
fallback: {text: "0.0.0.0", checked: false},
|
||||||
|
tip: "Set up static IPv4 address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
],
|
],
|
||||||
size: 'small',
|
size: 'small',
|
||||||
warnings: [
|
warnings: [
|
||||||
|
@ -1229,6 +1300,12 @@ const shop_data = {
|
||||||
'100Base-T Ethernet with PoE.',
|
'100Base-T Ethernet with PoE.',
|
||||||
'Can stabilize temperature of Sinara 5432 DAC or external devices containing TEC and thermistor.'
|
'Can stabilize temperature of Sinara 5432 DAC or external devices containing TEC and thermistor.'
|
||||||
],
|
],
|
||||||
|
crateless_options: [
|
||||||
|
{type: "SwitchLine", args: {title: "IPv4", outvar: "ip",
|
||||||
|
validator: {name: "ipv4"},
|
||||||
|
fallback: {text: "192.168.1.26/24", checked: false},
|
||||||
|
tip: "Set up IP address used by the device"}},
|
||||||
|
],
|
||||||
size: 'small',
|
size: 'small',
|
||||||
consumes: {
|
consumes: {
|
||||||
hp: 4
|
hp: 4
|
||||||
|
@ -1280,19 +1357,33 @@ const shop_data = {
|
||||||
validator: {name: "ipv4or6"},
|
validator: {name: "ipv4or6"},
|
||||||
fallback: {text: "DHCP", checked: false},
|
fallback: {text: "DHCP", checked: false},
|
||||||
tip: "Set up IP address used by the device"}},
|
tip: "Set up IP address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
||||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||||
fallback: {text: "125 MHz", checked: false}, validator: {name: "frequency", params: {min: 10e6, max: 1e9}}}},
|
fallback: {text: "125 MHz", checked: false}, validator: {name: "frequency", params: {min: 10e6, max: 1e9}}}},
|
||||||
{type: "Switch", args: {title: "Termination #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
{type: "Switch", args: {title: "Termination #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
||||||
{type: "Switch", args: {title: "Termination #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
{type: "Switch", args: {title: "Termination #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
||||||
],
|
],
|
||||||
|
crateless_options: [
|
||||||
|
{type: "SwitchLine", args: {title: "Static IPv4", outvar: "ip",
|
||||||
|
validator: {name: "ipv4"},
|
||||||
|
fallback: {text: "0.0.0.0", checked: false},
|
||||||
|
tip: "Set up static IPv4 address used by the device"}},
|
||||||
|
{type: "SwitchLine", args: {title: "MQTT broker address", outvar: "broker",
|
||||||
|
validator: {name: "ipv4OrHost"},
|
||||||
|
fallback: {text: "mqtt", checked: false},
|
||||||
|
tip: "Set up domain name or IPv4 of the MQTT broker"}},
|
||||||
|
],
|
||||||
size: 'big',
|
size: 'big',
|
||||||
warnings: [
|
warnings: [
|
||||||
"no_eem_source",
|
"no_eem_source",
|
||||||
"no_clk_source"
|
"no_clk_source"
|
||||||
],
|
],
|
||||||
consumes: {
|
consumes: {
|
||||||
hp: 4,
|
hp: 8,
|
||||||
eem: 1,
|
eem: 1,
|
||||||
clk: 1
|
clk: 1
|
||||||
}
|
}
|
||||||
|
@ -1318,7 +1409,7 @@ const shop_data = {
|
||||||
size: 'big',
|
size: 'big',
|
||||||
warnings: [],
|
warnings: [],
|
||||||
consumes: {
|
consumes: {
|
||||||
hp: 4,
|
hp: 8,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'kirdy': {
|
'kirdy': {
|
||||||
|
@ -1352,6 +1443,26 @@ const shop_data = {
|
||||||
hp: 8,
|
hp: 8,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'afws': {
|
||||||
|
id: 'afws',
|
||||||
|
name: 'Subscription',
|
||||||
|
name_number: 'AFWS',
|
||||||
|
name_codename: '',
|
||||||
|
price: 800,
|
||||||
|
image: '/images/shop/graphic-03_AFWS.svg',
|
||||||
|
specs: [
|
||||||
|
"Artiq Firmware Service for one variant for one year.",
|
||||||
|
"Includes support at helpdesk.",
|
||||||
|
"Included with purchase of any Carrier with no additional cost.",
|
||||||
|
],
|
||||||
|
crateless: true,
|
||||||
|
crateless_options: [
|
||||||
|
{type: "Line", args: {title: "Variant name", outvar: "variant_name", fallback: "",
|
||||||
|
tip: "Variant name can be found on the sticker on top of the crate. If you don't have one, leave the preferred name here."}},
|
||||||
|
],
|
||||||
|
size: 'big',
|
||||||
|
warnings: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
columns: {
|
columns: {
|
||||||
|
@ -1394,6 +1505,7 @@ const shop_data = {
|
||||||
itemIds: [
|
itemIds: [
|
||||||
'idc-bnc-adapter',
|
'idc-bnc-adapter',
|
||||||
'idc-sma-adapter',
|
'idc-sma-adapter',
|
||||||
|
'idc-mcx-adapter',
|
||||||
'hd68-idc-adapter',
|
'hd68-idc-adapter',
|
||||||
'vhdcicarrier']},
|
'vhdcicarrier']},
|
||||||
{ name: 'Servos',
|
{ name: 'Servos',
|
||||||
|
@ -1408,6 +1520,7 @@ const shop_data = {
|
||||||
'koster',
|
'koster',
|
||||||
'eem_pwr_mod',
|
'eem_pwr_mod',
|
||||||
'kirdy',
|
'kirdy',
|
||||||
|
'afws',
|
||||||
]}
|
]}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -1422,7 +1535,7 @@ const shop_data = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "spare",
|
id: "spare",
|
||||||
name: "Spare cards",
|
name: "Spare items",
|
||||||
crate_mode: "no_crate",
|
crate_mode: "no_crate",
|
||||||
items: [],
|
items: [],
|
||||||
warnings: [],
|
warnings: [],
|
||||||
|
|
Loading…
Reference in New Issue